-
Notifications
You must be signed in to change notification settings - Fork 42
[Feature Request] Supporting #[serde(flatten)] #8
Comments
Just to try to proceed in understanding what is happening, I let |
Thanks for the interesting feature request. I looked into the Serde-generated code for serialization (which is always easier than deserialization to get started). So, if we start with this #[derive(Serialize)]
struct Foo {
a: u64,
#[serde(flatten)]
b: Bar,
} then Serde generates roughly this: (I minimized the code by hand for readability) impl Serialize for Foo {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut serde_state = Serializer::serialize_map(serializer, None)?;
SerializeMap::serialize_entry(&mut serde_state, "a", &self.a)?;
Serialize::serialize(
&&self.b,
private::ser::FlatMapSerializer(&mut serde_state),
)?;
SerializeMap::end(serde_state)
}
} Unfortunately, it looks like using This is a bit unfortunate in this simple use case where (if I understand the request correctly) we just wanted to inline the second struct like this: struct Foo {
a: u64,
c: u32,
d: u16,
} assuming for instance:
For binary formats like bincode, it seems to me that this behavior of Until we have a more targeted macro, in this case, I would consider writing use serde::{de::Deserializer, ser::SerializeStruct, ser::Serializer, Deserialize, Serialize};
struct Foo {
a: u64,
b: Bar,
}
struct Bar {
c: u8,
d: u16,
}
impl Serialize for Foo {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("Foo", 3)?;
state.serialize_field("a", &self.a)?;
state.serialize_field("c", &self.b.c)?;
state.serialize_field("d", &self.b.d)?;
state.end()
}
}
#[derive(Deserialize)]
#[serde(rename = "Foo")]
struct FlatFoo {
a: u64,
c: u8,
d: u16,
}
impl<'de> Deserialize<'de> for Foo {
fn deserialize<D>(deserializer: D) -> Result<Foo, D::Error>
where
D: Deserializer<'de>,
{
let value = FlatFoo::deserialize(deserializer)?;
Ok(Foo {
a: value.a,
b: Bar {
c: value.c,
d: value.d,
},
})
}
} |
p.s. This being said, the comment "// Not needed since ..." is at best confusing and needs to be fixed. |
See also the discussion in bincode-org/bincode#245 |
Thanks for the reply and research! So if I understand correctly,
Do you mean that this crate will eventually rely on a derive macro like many other introspection crates? Does that makes the |
Just an idea: What if this crate defines a trait that is blanket-implemented on all I read in the link you provided:
But we have this information don't we? And if we use a trait to expose this information for all Edit: Just realized something: our |
I actually meant: until a macro (say |
🚀 Feature Request
I would like to be able to generate a registry for these structs
But I get the error
NotSupported("deserialize_identifier")
.In
serde-reflection/src/de.rs
I seeI can try to fix this and implement support for
#[serde(flatten)]
, but I wonder:Can someone explain the comment? It seems like this function should be supported after all. What was the previous assumption and why is it violated with
#[serde(flatten)]
?The text was updated successfully, but these errors were encountered: