From 2aa4a82499d4becd2284cdb482213d541b8804dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 16:29:10 +0200 Subject: Adding upstream version 86.0.1. Signed-off-by: Daniel Baumann --- third_party/rust/serde_with/src/with_prefix.rs | 607 +++++++++++++++++++++++++ 1 file changed, 607 insertions(+) create mode 100644 third_party/rust/serde_with/src/with_prefix.rs (limited to 'third_party/rust/serde_with/src/with_prefix.rs') diff --git a/third_party/rust/serde_with/src/with_prefix.rs b/third_party/rust/serde_with/src/with_prefix.rs new file mode 100644 index 0000000000..776927d365 --- /dev/null +++ b/third_party/rust/serde_with/src/with_prefix.rs @@ -0,0 +1,607 @@ +use std::fmt; + +use serde::{ + de::{self, DeserializeSeed, Deserializer, IgnoredAny, IntoDeserializer, MapAccess, Visitor}, + forward_to_deserialize_any, + ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer}, +}; + +/// Serialize with an added prefix on every field name and deserialize by +/// trimming away the prefix. +/// +/// **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_prefix` wrapper. +/// More details can be found in [this issue][issue-with_prefix-deny_unknown_fields]. +/// +/// # Example +/// +/// The [Challonge REST API] likes to use prefixes to group related fields. In +/// simplified form, their JSON may resemble the following: +/// +/// [Challonge REST API]: https://api.challonge.com/v1/documents/matches/show +/// +/// ```json +/// { +/// "player1_name": "name1", +/// "player1_votes": 1, +/// "player2_name": "name2", +/// "player2_votes": 2 +/// } +/// ``` +/// +/// In Rust we would ideally like to model this data as a pair of `Player` +/// structs, rather than repeating the fields of `Player` for each prefix. +/// +/// ```rust +/// struct Match { +/// player1: Player, +/// player2: Player, +/// } +/// +/// struct Player { +/// name: String, +/// votes: u64, +/// } +/// ``` +/// +/// This `with_prefix!` macro produces an adapter that adds a prefix onto field +/// names during serialization and trims away the prefix during deserialization. +/// An implementation of the Challonge API would use `with_prefix!` like this: +/// +/// ```rust +/// extern crate serde_derive; +/// extern crate serde_json; +/// extern crate serde_with; +/// +/// use serde_derive::{Deserialize, Serialize}; +/// use serde_json::json; +/// use serde_with::with_prefix; +/// +/// #[derive(Serialize, Deserialize)] +/// struct Match { +/// #[serde(flatten, with = "prefix_player1")] +/// player1: Player, +/// #[serde(flatten, with = "prefix_player2")] +/// player2: Player, +/// } +/// +/// #[derive(Serialize, Deserialize)] +/// struct Player { +/// name: String, +/// votes: u64, +/// } +/// +/// with_prefix!(prefix_player1 "player1_"); +/// with_prefix!(prefix_player2 "player2_"); +/// # +/// # const EXPECTED: &str = r#"{ +/// # "player1_name": "name1", +/// # "player1_votes": 1, +/// # "player2_name": "name2", +/// # "player2_votes": 2 +/// # }"#; +/// +/// fn main() { +/// let m = Match { +/// player1: Player { +/// name: "name1".to_owned(), +/// votes: 1, +/// }, +/// player2: Player { +/// name: "name2".to_owned(), +/// votes: 2, +/// }, +/// }; +/// +/// let j = serde_json::to_string_pretty(&m).unwrap(); +/// println!("{}", j); +/// # +/// # assert_eq!(j, EXPECTED); +/// } +/// ``` +/// +/// [`deny_unknown_fields`]: https://serde.rs/container-attrs.html#deny_unknown_fields +/// [issue-with_prefix-deny_unknown_fields]: https://github.com/jonasbb/serde_with/issues/57 +#[macro_export] +macro_rules! with_prefix { + ($module:ident $prefix:expr) => { + mod $module { + use $crate::{ + serde::{Deserialize, Deserializer, Serialize, Serializer}, + with_prefix::WithPrefix, + }; + + #[allow(dead_code)] + pub fn serialize(object: &T, serializer: S) -> Result + where + T: Serialize, + S: Serializer, + { + object.serialize(WithPrefix { + delegate: serializer, + prefix: $prefix, + }) + } + + #[allow(dead_code)] + pub fn deserialize<'de, T, D>(deserializer: D) -> Result + where + T: Deserialize<'de>, + D: Deserializer<'de>, + { + T::deserialize(WithPrefix { + delegate: deserializer, + prefix: $prefix, + }) + } + } + }; +} + +#[allow(missing_debug_implementations)] +pub struct WithPrefix<'a, T> { + pub delegate: T, + pub prefix: &'a str, +} + +impl<'a, T> Serialize for WithPrefix<'a, T> +where + T: Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.delegate.serialize(WithPrefix { + delegate: serializer, + prefix: self.prefix, + }) + } +} + +impl<'a, S> Serializer for WithPrefix<'a, S> +where + S: Serializer, +{ + type Ok = S::Ok; + type Error = S::Error; + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeTupleVariant = Impossible; + type SerializeMap = WithPrefix<'a, S::SerializeMap>; + type SerializeStruct = WithPrefix<'a, S::SerializeMap>; + type SerializeStructVariant = Impossible; + + fn serialize_bool(self, _v: bool) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_i8(self, _v: i8) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_i16(self, _v: i16) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_i32(self, _v: i32) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_i64(self, _v: i64) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_u8(self, _v: u8) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_u16(self, _v: u16) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_u32(self, _v: u32) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_u64(self, _v: u64) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_f32(self, _v: f32) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_f64(self, _v: f64) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_char(self, _v: char) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_str(self, v: &str) -> Result { + self.delegate + .collect_str(&format_args!("{}{}", self.prefix, v)) + } + + fn serialize_bytes(self, _v: &[u8]) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_none(self) -> Result { + self.delegate.serialize_none() + } + + fn serialize_some(self, value: &T) -> Result + where + T: ?Sized + Serialize, + { + self.delegate.serialize_some(&WithPrefix { + delegate: value, + prefix: self.prefix, + }) + } + + fn serialize_unit(self) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_newtype_struct( + self, + _name: &'static str, + _value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } + + fn serialize_map(self, len: Option) -> Result { + Ok(WithPrefix { + delegate: self.delegate.serialize_map(len)?, + prefix: self.prefix, + }) + } + + fn serialize_struct( + self, + _name: &'static str, + len: usize, + ) -> Result { + self.serialize_map(Some(len)) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(ser::Error::custom("wrong type for with_prefix")) + } +} + +impl<'a, S> SerializeMap for WithPrefix<'a, S> +where + S: SerializeMap, +{ + type Ok = S::Ok; + type Error = S::Error; + + fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + self.delegate.serialize_key(&WithPrefix { + delegate: key, + prefix: self.prefix, + }) + } + + fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + self.delegate.serialize_value(value) + } + + fn serialize_entry(&mut self, key: &K, value: &V) -> Result<(), Self::Error> + where + K: ?Sized + Serialize, + V: ?Sized + Serialize, + { + self.delegate.serialize_entry( + &WithPrefix { + delegate: key, + prefix: self.prefix, + }, + value, + ) + } + + fn end(self) -> Result { + self.delegate.end() + } +} + +impl<'a, S> SerializeStruct for WithPrefix<'a, S> +where + S: SerializeMap, +{ + type Ok = S::Ok; + type Error = S::Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + self.delegate + .serialize_entry(&format!("{}{}", self.prefix, key), value) + } + + fn end(self) -> Result { + self.delegate.end() + } +} + +impl<'de, 'a, T> DeserializeSeed<'de> for WithPrefix<'a, T> +where + T: DeserializeSeed<'de>, +{ + type Value = T::Value; + + fn deserialize(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + self.delegate.deserialize(WithPrefix { + delegate: deserializer, + prefix: self.prefix, + }) + } +} + +impl<'de, 'a, D> Deserializer<'de> for WithPrefix<'a, D> +where + D: Deserializer<'de>, +{ + type Error = D::Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.delegate.deserialize_map(WithPrefix { + delegate: visitor, + prefix: self.prefix, + }) + } + + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.delegate.deserialize_any(WithPrefixOption { + first_key: None, + delegate: visitor, + prefix: self.prefix, + }) + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.delegate.deserialize_identifier(WithPrefix { + delegate: visitor, + prefix: self.prefix, + }) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf unit unit_struct newtype_struct seq tuple tuple_struct + map struct enum ignored_any + } +} + +impl<'de, 'a, V> Visitor<'de> for WithPrefix<'a, V> +where + V: Visitor<'de>, +{ + type Value = V::Value; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + self.delegate.expecting(formatter) + } + + fn visit_map(self, map: A) -> Result + where + A: MapAccess<'de>, + { + self.delegate.visit_map(WithPrefix { + delegate: map, + prefix: self.prefix, + }) + } +} + +impl<'de, 'a, A> MapAccess<'de> for WithPrefix<'a, A> +where + A: MapAccess<'de>, +{ + type Error = A::Error; + + fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> + where + K: DeserializeSeed<'de>, + { + while let Some(s) = self.delegate.next_key::()? { + if s.starts_with(self.prefix) { + let without_prefix = s[self.prefix.len()..].into_deserializer(); + return seed.deserialize(without_prefix).map(Some); + } + self.delegate.next_value::()?; + } + Ok(None) + } + + fn next_value_seed(&mut self, seed: V) -> Result + where + V: DeserializeSeed<'de>, + { + self.delegate.next_value_seed(seed) + } +} + +#[allow(missing_debug_implementations)] +pub struct WithPrefixOption<'a, T> { + first_key: Option, + delegate: T, + prefix: &'a str, +} + +impl<'de, 'a, V> Visitor<'de> for WithPrefixOption<'a, V> +where + V: Visitor<'de>, +{ + type Value = V::Value; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + self.delegate.expecting(formatter) + } + + fn visit_unit(self) -> Result + where + E: de::Error, + { + self.delegate.visit_none() + } + + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + while let Some(s) = map.next_key::()? { + if s.starts_with(self.prefix) { + return self.delegate.visit_some(WithPrefixOption { + first_key: Some(s), + delegate: map, + prefix: self.prefix, + }); + } + map.next_value::()?; + } + self.delegate.visit_none() + } +} + +impl<'de, 'a, A> Deserializer<'de> for WithPrefixOption<'a, A> +where + A: MapAccess<'de>, +{ + type Error = A::Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_map(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +impl<'de, 'a, A> MapAccess<'de> for WithPrefixOption<'a, A> +where + A: MapAccess<'de>, +{ + type Error = A::Error; + + fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> + where + K: DeserializeSeed<'de>, + { + if let Some(s) = self.first_key.take() { + let without_prefix = s[self.prefix.len()..].into_deserializer(); + return seed.deserialize(without_prefix).map(Some); + } + while let Some(s) = self.delegate.next_key::()? { + if s.starts_with(self.prefix) { + let without_prefix = s[self.prefix.len()..].into_deserializer(); + return seed.deserialize(without_prefix).map(Some); + } + self.delegate.next_value::()?; + } + Ok(None) + } + + fn next_value_seed(&mut self, seed: V) -> Result + where + V: DeserializeSeed<'de>, + { + self.delegate.next_value_seed(seed) + } +} -- cgit v1.2.3