Rust serde远程派生trait边界未满足

jjjwad0x  于 2023-05-22  发布在  其他
关注(0)|答案(1)|浏览(167)
#[derive(serde::Serialize, serde::Deserialize)]
#[serde(remote = "ExternalType")]
pub struct ExternalTypeWrapper {
   ...
}

#[derive(serde::Serialize, serde::Deserialize)]
struct X {
    // works
    #[serde(with = "ExternalTypeWrapper")]
    x1: ExternalType,

    // does not work
    #[serde(with = "Vec::<ExternalTypeWrapper>")]
    x2: Vec<ExternalType>,
}

为什么我的远程派生(反)序列化只对普通类型有效,但如果它被 Package 在类似Vec的东西中就不行了?这将导致以下错误:

the function or associated item `serialize` exists for struct `Vec<ExternalTypeWrapper>`, but its trait bounds were not satisfied
the following trait bounds were not satisfied:
`ExternalTypeWrapper: Serialize`
which is required by `Vec<ExternalTypeWrapper>: Serialize`
`Vec<ExternalTypeWrapper>: Serialize`
which is required by `&Vec<ExternalTypeWrapper>: Serialize`
`Vec<ExternalTypeWrapper>: Serialize`
which is required by `&mut Vec<ExternalTypeWrapper>: Serialize`

(与Deserialize trait类似)

mwg9r5ms

mwg9r5ms1#

这是不可能的只有serde。有一个关于它的old bug report,但serde维护者没有解决方案。你可以使用serde_with来解决这个问题。用户指南中解释了这些步骤。
使用两个trait SerializeAs/DeserializeAs,它们的工作方式类似于serde trait,您可以添加对嵌套类型的支持,如OptionVec。然后使用serde_as而不是serde(with = "...")注解结构体和字段。

/*
[dependencies]
serde = "1"
serde_with = "3"
*/

pub struct ExternalType {
    foo: (),
}

fn main() {
    #[derive(serde::Serialize, serde::Deserialize)]
    #[serde(remote = "ExternalType")]
    pub struct ExternalTypeWrapper {
        foo: (),
    }

    // https://docs.rs/serde_with/latest/serde_with/guide/serde_as/index.html#using-serde_as-with-serdes-remote-derives
    impl serde_with::SerializeAs<ExternalType> for ExternalTypeWrapper {
        fn serialize_as<S>(value: &ExternalType, serializer: S) -> Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            ExternalTypeWrapper::serialize(value, serializer)
        }
    }

    impl<'de> serde_with::DeserializeAs<'de, ExternalType> for ExternalTypeWrapper {
        fn deserialize_as<D>(deserializer: D) -> Result<ExternalType, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            ExternalTypeWrapper::deserialize(deserializer)
        }
    }

    #[serde_with::serde_as]
    #[derive(serde::Serialize, serde::Deserialize)]
    struct X {
        // works
        #[serde(with = "ExternalTypeWrapper")]
        x1: ExternalType,

        // does not work
        #[serde_as(as = "Vec<ExternalTypeWrapper>")]
        x2: Vec<ExternalType>,
    }
}

Solution on Rustexplorer

相关问题