Reputation: 149
#[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>,
}
Why does my remote derived (De)Serialize only work for the plain type, but not if it is wrapped in something like a Vec? This gives the following error:
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`
(analogous for the Deserialize trait)
Upvotes: 0
Views: 163
Reputation: 2583
This is not possible with only serde. There is an old bug report about it, but no solutions from the serde maintainers.
You can use serde_with
to solve it. The steps are explained in the user guide.
Using the two traits SerializeAs
/DeserializeAs
, which work similar to the serde ones, you can add support for nesting types, like Option
or Vec
. You then annotate the struct and field with serde_as
instead of using 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>,
}
}
Upvotes: 1