如何在 `serde::ser::Serialize` 的实现中跳过序列化?

How to skip serialization in impl of `serde::ser::Serialize`?

我想根据 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 = ()>`

但我不知道如何指定建议的约束条件 <Ok = ()>

这将在一定程度上取决于序列化程序。一些序列化器(例如 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)
    }
}

but I have no idea on how to specify the suggested constraint <Ok = ()>

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