如何实现反序列化和派生它

fad*_*bee 1 rust serde

我有一个struct Foo我想在 JSON 中序列化为一个由两部分组成的字符串,例如"01abcdef:42",但在 bincode 中是正常的。

(出于大小原因,我需要在 bincode 中正常序列化它。在某些情况下,Bar或者Baz是大字节数组,它们占用的空间是十六进制的两倍多。)

我当前的代码正是我想要的:

pub struct Foo {     
        pub bar: Bar,
        pub baz: Baz
}

impl<'de> ::serde::Deserialize<'de> for Foo {
        fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Foo, D::Error> {
                use ::serde::de::Error;
                use core::str::FromStr;

                if d.is_human_readable() {
                        let sl: &str = ::serde::Deserialize::deserialize(d)?;
                        Foo::from_str(sl).map_err(D::Error::custom)
                } else {
                        let clone: FooClone = FooClone::deserialize(d)?;
                        Ok(Foo { bar: clone.bar, baz: clone.baz })
                }
        }
}

#[derive(Deserialize)]
pub struct FooClone {           
        pub bar: Bar,
        pub baz: Baz
}
Run Code Online (Sandbox Code Playgroud)

我需要手动维护FooCloneFoo.

我已经读过这篇文章,但是比这个 struct clone 要维护的代码要多得多。

我如何手动实现Deserialize(处理 JSON 两部分字符串)并Deserialize相同的结构派生(消除FooClone)?

jon*_*sbb 5

像这样的事情应该有效。您仍然使用派生来生成deserialize函数。但是由于它是远程派生的类型不会实现Deserialize,而是获得一个固有的功能,您可以在手动Deserialize实现中调用它。

#[derive(serde::Deserialize)]
#[serde(remote = "Self")]
pub struct Foo {
    pub bar: Bar,
    pub baz: Baz,
}

impl<'de> ::serde::Deserialize<'de> for Foo {
    fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Foo, D::Error> {
        use ::serde::de::Error;
        use core::str::FromStr;

        if d.is_human_readable() {
            let sl: &str = ::serde::Deserialize::deserialize(d)?;
            Foo::from_str(sl).map_err(D::Error::custom)
        } else {
            Foo::deserialize(d)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)