Is there a way to add the value of a method to the serialization output of serde
when the struct derives Serialize
? I'm looking for something like a "virtual field".
I know I can define my own Serializer
/ Visitor
or use serde_json::builder
to get a Value
, I just wanted to check first if there was any way to do this using serde_macro
magic.
To be clear I want something like this:
#[derive(Serialize, Deserialize, Debug)]
struct Foo {
bar: String,
#[serde(call="Foo::baz")]
baz: i32 // but this is not a real field
}
impl Foo {
fn baz(&self) -> i32 { self.bar.len() as i32 }
}
Implementing Serialize. The Serialize trait looks like this: This method's job is to take your type (&self) and map it into the Serde data model by invoking exactly one of the methods on the given Serializer. In most cases Serde's derive is able to generate an appropriate implementation of Serialize for structs and enums defined in your crate.
Implementing Serialize The Serialize trait looks like this: pub trait Serialize { fn serialize<S> (&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer; } This method's job is to take your type (&self) and map it into the Serde data model by invoking exactly one of the methods on the given Serializer.
Serde provides Serialize implementations for many Rust primitive and standard library types. The complete list is here. All of these can be serialized using Serde out of the box. Additionally, Serde provides a procedural macro called serde_derive to automatically generate Serialize implementations for structs and enums in your program.
This method's job is to take your type (&self) and map it into the Serde data modelby invoking exactly one of the methods on the given Serializer. In most cases Serde's deriveis able to generate an appropriate implementation of Serializefor structs and enums defined in your crate.
Here is what I am using now. It's still verbose, and I don't know if it is the best way to handle this, but I thought I would add it here for the record:
#[derive(Deserialize, Debug)]
struct Foo {
bar: String
}
impl Foo {
fn baz(&self) -> i32 { self.bar.len() as i32 }
}
impl ::serde::Serialize for Foo {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ::serde::Serializer {
#[derive(Serialize)]
struct Extended<'a> {
bar: &'a String,
baz: i32
}
let ext = Extended {
bar: &self.bar,
baz: self.baz()
};
Ok(try!(ext.serialize(serializer)))
}
}
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