Macro serde_with::serde_conv [−][src]
macro_rules! serde_conv { ($m:ident, $t:ty, $ser:expr, $de:expr) => { ... }; ($vis:vis $m:ident, $t:ty, $ser:expr, $de:expr) => { ... }; }
Expand description
Create new conversion adapters from functions
The macro lets you create a new converter, which is usable for serde’s with-attribute and #[serde_as]
.
Its main use case is to write simple converters for types which are not serializable.
Another use-case is to change the serialization behavior if the implemented Serialize
/Deserialize
trait is insufficient.
The macro takes four arguments:
- The name of the converter type.
The type can be prefixed with a visibility modifies like
pub
orpub(crate)
. By default the type is not marked as public (pub(self)
). - The type
T
we want to extent with custom behavior. - A function or macro taking a
&T
and returning a serializable type. - A function or macro taking a deserializable type and returning a
Result<T, E>
. The error typeE
must implementDisplay
.
Example
In this example we write custom serialization behavior for a Rgb
type.
We want to serialize it as a [u8; 3]
.
#[derive(Clone, Copy, Debug, PartialEq)] struct Rgb { red: u8, green: u8, blue: u8, } serde_with::serde_conv!( RgbAsArray, Rgb, |rgb: &Rgb| [rgb.red, rgb.green, rgb.blue], |value: [u8; 3]| -> Result<_, std::convert::Infallible> { Ok(Rgb { red: value[0], green: value[1], blue: value[2], }) } ); ////////////////////////////////////////////////// // We define some colors to be used later let green = Rgb {red: 0, green: 255, blue: 0}; let orange = Rgb {red: 255, green: 128, blue: 0}; let pink = Rgb {red: 255, green: 0, blue: 255}; ////////////////////////////////////////////////// // We can now use the `RgbAsArray` adapter with `serde_as`. #[serde_with::serde_as] #[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)] struct Colors { #[serde_as(as = "RgbAsArray")] one_rgb: Rgb, #[serde_as(as = "Vec<RgbAsArray>")] rgbs_in_vec: Vec<Rgb>, } let data = Colors { one_rgb: orange, rgbs_in_vec: vec![green, pink], }; let json = serde_json::json!({ "one_rgb": [255, 128, 0], "rgbs_in_vec": [ [0, 255, 0], [255, 0, 255] ] }); assert_eq!(json, serde_json::to_value(&data).unwrap()); assert_eq!(data, serde_json::from_value(json).unwrap()); ////////////////////////////////////////////////// // The types generated by `serde_conv` is also compatible with serde's with attribute #[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)] struct ColorsWith { #[serde(with = "RgbAsArray")] rgb_with: Rgb, } let data = ColorsWith { rgb_with: pink, }; let json = serde_json::json!({ "rgb_with": [255, 0, 255] }); assert_eq!(json, serde_json::to_value(&data).unwrap()); assert_eq!(data, serde_json::from_value(json).unwrap());