【问题标题】:How to skip serialization in impl of `serde::ser::Serialize`?如何在`serde::ser::Serialize`的impl中跳过序列化?
【发布时间】:2021-10-26 19:31:36
【问题描述】:

我想完全基于 Serialize 的自定义实现中的某些值跳过序列化

impl Serialize for MyType {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match &self.value {
            Action::Serialize => //serialize.serialize_struct(  etc...
            Action::NoSerialize => Ok(()) // <= Error. How do I return Ok and skip serialization ? 
       }
    }
}

错误信息显示

mismatched types
expected associated type `<S as mystuff::_::_serde::Serializer>::Ok`
         found unit type `()`rustcE0308
mod.rs(160, 22): consider constraining the associated type `<S as mystuff::_::_serde::Serializer>::Ok` to `()`: `<Ok = ()>`

但我不知道如何指定建议的约束&lt;Ok = ()&gt;

【问题讨论】:

    标签: rust serde


    【解决方案1】:

    这将取决于序列化程序。一些序列化程序(例如 Bincode)会跳过单位值,因此您可以使用 Serializer::serialize_unit()。然而,其他人,如serde_json,将给出单位值,例如null.

    问题在于,在某些情况下,序列化程序需要一个值。例如,如果您要序列化为 Json 映射(对象字面量),则没有值的键是没有意义的,但您甚至在检查值之前就已经序列化了键。

    因此,要一般地跳过值,您需要自定义包含该值的结构或集合的序列化,以确定正确的操作。在某些情况下,这可能意味着为“父”类型编写自定义序列化,以使其了解需要跳过的内容。其他时候,你可以使用serde属性来自定义:

    #[derive(Serialize)]
    pub struct Parent {
        #[serde(skip_serializing_if = "MyType::no_serialize")]
        pub my_value: MyType,
    }
    
    impl MyType {
        fn no_serialize(&self) -> bool {
            matches!(self, Action::NoSerialize)
        }
    }
    

    但我不知道如何指定建议的约束&lt;Ok = ()>

    在这种情况下,该建议是转移注意力。 Ok 这里是您正在使用的 Serializer 的关联类型。这不是您可以更改的,将其更改为 () 将意味着创建一个序列化格式,该格式对于 所有 值都是空的。

    【讨论】:

    • 谢谢。由于我无法更改父级,因此我采用了不同的策略(以及无数的注释......)
    猜你喜欢
    • 2022-11-02
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-03
    • 2022-11-10
    • 2018-08-25
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多