rust - 如何同时实现反序列化和派生它

标签 rust serde

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

(由于大小原因,我需要它在 bincode 中正常序列化。在某些情况下,BarBaz 是大型字节数组,占用两倍以上的空间十六进制。)

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

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
}

我需要手动维护 FooClone 作为 Foo 的相同副本。

我已阅读 this但与此结构克隆相比,需要维护的代码要多得多。

我怎样才能既手动实现Deserialize(以处理 JSON 两部分字符串)又为相同结构派生Deserialize (消除 FooClone)?

最佳答案

像这样的东西应该可以工作。您仍然使用 derive 生成​​ 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)
        }
    }
}

关于rust - 如何同时实现反序列化和派生它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67543624/

相关文章:

rust - 我可以在 Rust 中创建以元组作为值的枚举吗?

json - 有没有更好的方法将 Rust BSON 文档直接转换为 JSON?

rust - 当迭代器使用容器时,是否可以从循环中返回容器?

rust - 在使用Serde进行序列化时,是否有一种方法可以将结构的字段分组,例如 “flatten”属性的逆函数?

testing - 使用 cfg 属性有条件地计算间接函数调用的最佳方法是什么?

rust - 我可以在 Rust 中将 const 与重载运算符一起使用吗?

rust - 在 Rust 中,将带有可选参数的平面 JSON 反序列化为嵌套结构和枚举

rust - 将数据序列化到结构模型中,其中两个字段的数据是根据结构中的其他字段计算的

rust - 克隆存储闭包的结构

rust - 什么时候应该在 Rust 中使用内联?