/// Serialize with an added suffix on every field name and deserialize by /// trimming away the suffix. /// /// You can set the visibility of the generated module by suffixing the module name with a module visibility. /// `with_suffix!(pub(crate) suffix_foo "_foo");` creates a module with `pub(crate)` visibility. /// The visibility is optional and by default `pub(self)`, i.e., private visibility is assumed. /// /// **Note:** Use of this macro is incompatible with applying the [`deny_unknown_fields`] attribute /// on the container. /// While deserializing, it will always warn about unknown fields, even though they are processed /// by the `with_suffix` wrapper. /// More details can be found in [this issue][issue-with_suffix-deny_unknown_fields]. /// /// # Example /// /// [Factorio Prototype tables] like to use suffixes to group related fields. In /// simplified form, their JSON representation may resemble the following: /// /// [Factorio Prototype tables]: https://lua-api.factorio.com/2.0.13/types/PipePictures.html /// /// ```json /// { /// "frames": 4, /// "spritesheet": "normal", /// "frames_frozen": 1, /// "spritesheet_frozen": "frozen", /// "frames_visualization": 2, /// "spritesheet_visualization": "vis", /// } /// ``` /// /// In Rust, we would ideally like to model this data as a couple of `SpriteData` /// structs, rather than repeating the fields of `SpriteData` for each suffix. /// /// ```rust /// # #[allow(dead_code)] /// struct Graphics { /// normal: SpriteData, /// frozen: SpriteData, /// visualization: SpriteData, /// } /// /// # #[allow(dead_code)] /// struct SpriteData { /// frames: u64, /// spritesheet: String, /// } /// ``` /// /// This `with_suffix!` macro produces an adapter that adds a suffix onto field /// names during serialization and trims away the suffix during deserialization. /// An implementation for the mentioned situation would use `with_suffix!` like this: /// /// ```rust /// use serde::{Deserialize, Serialize}; /// use serde_with::with_suffix; /// /// #[derive(Serialize, Deserialize)] /// struct Graphics { /// #[serde(flatten)] /// normal: SpriteData, /// #[serde(flatten, with = "suffix_frozen")] /// frozen: SpriteData, /// #[serde(flatten, with = "suffix_visualization")] /// visualization: SpriteData, /// } /// /// #[derive(Serialize, Deserialize)] /// struct SpriteData { /// frames: u64, /// spritesheet: String, /// } /// /// with_suffix!(suffix_frozen "_frozen"); /// // You can also set the visibility of the generated suffix module, the default is private. /// with_suffix!(pub suffix_visualization "_visualization"); /// # /// # const EXPECTED: &str = r#"{ /// # "frames": 4, /// # "spritesheet": "normal", /// # "frames_frozen": 1, /// # "spritesheet_frozen": "frozen", /// # "frames_visualization": 2, /// # "spritesheet_visualization": "vis" /// # }"#; /// /// fn main() { /// let g = Graphics { /// normal: SpriteData { /// frames: 4, /// spritesheet: "normal".to_owned(), /// }, /// frozen: SpriteData { /// frames: 1, /// spritesheet: "frozen".to_owned(), /// }, /// visualization: SpriteData { /// frames: 2, /// spritesheet: "vis".to_owned(), /// }, /// }; /// /// let j = serde_json::to_string_pretty(&g).unwrap(); /// println!("{}", j); /// # /// # assert_eq!(j, EXPECTED); /// } /// ``` /// /// [`deny_unknown_fields`]: https://serde.rs/container-attrs.html#deny_unknown_fields /// [issue-with_suffix-deny_unknown_fields]: https://github.com/jonasbb/serde_with/issues/57 #[macro_export]
macro_rules! with_suffix {
($module:ident $suffix:expr) => {$crate::with_suffix!(pub(self) $module $suffix);};
($vis:vis $module:ident $suffix:expr) => {
$vis mod $module { use $crate::serde::{Deserialize, Deserializer, Serialize, Serializer}; use $crate::with_suffix::WithSuffix;
impl<T> Serialize for WithSuffix<'_, T> where
T: Serialize,
{ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where
S: Serializer,
{ self.delegate.serialize(WithSuffix {
delegate: serializer,
suffix: self.suffix,
})
}
}
impl<'a, S> Serializer for WithSuffix<'a, S> where
S: Serializer,
{ type Ok = S::Ok; type Error = S::Error; type SerializeSeq = Impossible<Self::Ok, Self::Error>; type SerializeTuple = Impossible<Self::Ok, Self::Error>; type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>; type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>; type SerializeMap = WithSuffix<'a, S::SerializeMap>; type SerializeStruct = WithSuffix<'a, S::SerializeMap>; type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;
fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
Err(SerError::custom("wrong type for with_suffix"))
}
fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
Err(SerError::custom("wrong type for with_suffix"))
}
fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
Err(SerError::custom("wrong type for with_suffix"))
}
fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
Err(SerError::custom("wrong type for with_suffix"))
}
fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
Err(SerError::custom("wrong type for with_suffix"))
}
fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
Err(SerError::custom("wrong type for with_suffix"))
}
fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
Err(SerError::custom("wrong type for with_suffix"))
}
fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
Err(SerError::custom("wrong type for with_suffix"))
}
fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
Err(SerError::custom("wrong type for with_suffix"))
}
fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
Err(SerError::custom("wrong type for with_suffix"))
}
fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
Err(SerError::custom("wrong type for with_suffix"))
}
fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
Err(SerError::custom("wrong type for with_suffix"))
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.