I need to to use custom implementations of Serialize
and Deserialize
, but i could not figure out how to do something like #[serde(flatten)]
does, does anyone know?
Note: i know i could completely re-write the full implementation of the lower elements into the higher one, but the lower elements implement Serialize
(and Deserialize
), so i am searching for a way to add that to something like serialize_struct
.
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Nested {
somefield2: String,
}
#[derive(Debug, PartialEq)]
struct TopLevel {
somefield1: usize,
nested: Nested,
}
impl Serialize for TopLevel {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// How to do this properly?
let mut do_struct = serializer.serialize_struct("Named", 2)?;
do_struct.serialize_field("somefield1", &self.somefield1)?;
// how to add everything from "self.nested" as the same level as this one?
// JSON example: { somefield1: 0, somefield2: 0 }
return do_struct.end();
}
}
impl<'de> Deserialize<'de> for TopLevel {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
// Same question as in "Serialize", how to do this properly in here?
// Here is currently no example code, because i try to figure out "Serialize" first
todo!();
}
}
Versions used:
1.0.133
1.58.1
Note: i have already read Implementing Serialize and tried to search issues / stackoverflow but could not find anything related to that.
You could try doing something like this for Serialize
and something similar for Deserialize
:
struct FakeStructFlatteningSerializer<'a, SS: SerializeStruct>(&'a mut SS);
impl Serializer<'a, SS: SerializeStruct> for FakeStructFlatteningSerializer<'a, SS> {
type Ok = ();
type Error = SS::Error;
type SerializeStruct = FakeStructFlatteningSerializeStruct<'a, SS>;
// return Impossible for everything else
fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct, Self::Error> {
// ignore name and len!
Ok(FakeStructFlatteningSerializeStruct(self.0))
}
}
struct FakeStructFlatteningSerializeStruct<'a, SS: SerializeStruct>(&'a mut SS);
impl<'a, SS: SerializeStruct> SerializeStruct for FakeStructFlatteningSerializeStruct<'a, SS> {
type Ok = ();
type Error = SS::Error;
fn serialize_field<T: Serialize + ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> {
self.0.serialize_field(key, value)
}
fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> {
self.0.skip_field(key)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
// ignore!
Ok(())
}
}
impl Serialize for TopLevel {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// len needs to include the flattened fields
let mut do_struct = serializer.serialize_struct("Named", 3)?;
do_struct.serialize_field("somefield1", &self.somefield1)?;
self.nested.serialize(FakeStructFlatteningSerializer(&mut do_struct));
return do_struct.end();
}
}
You could alternatively try to figure out how Serde does it; this might be where: https://github.com/serde-rs/serde/blob/dc0c0dcba17dd8732cd8721a7ef556afcb04c6c0/serde_derive/src/ser.rs#L953-L1037, https://github.com/serde-rs/serde/blob/fb2fe409c8f7ad6c95e3096e5e9ede865c8cfb49/serde_derive/src/de.rs#L2560-L2578
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With