serde_with/
with_prefix.rs

1use crate::prelude::*;
2
3/// Serialize with an added prefix on every field name and deserialize by
4/// trimming away the prefix.
5///
6/// You can set the visibility of the generated module by prefixing the module name with a module visibility.
7/// `with_prefix!(pub(crate) prefix_foo "foo_");` creates a module with `pub(crate)` visibility.
8/// The visibility is optional and by default `pub(self)`, i.e., private visibility is assumed.
9///
10/// **Note:** Use of this macro is incompatible with applying the [`deny_unknown_fields`] attribute
11/// on the container.
12/// While deserializing, it will always warn about unknown fields, even though they are processed
13/// by the `with_prefix` wrapper.
14/// More details can be found in [this issue][issue-with_prefix-deny_unknown_fields].
15///
16/// # Example
17///
18/// The [Challonge REST API] likes to use prefixes to group related fields. In
19/// simplified form, their JSON may resemble the following:
20///
21/// [Challonge REST API]: https://api.challonge.com/v1/documents/matches/show
22///
23/// ```json
24/// {
25///   "player1_name": "name1",
26///   "player1_votes": 1,
27///   "player2_name": "name2",
28///   "player2_votes": 2
29/// }
30/// ```
31///
32/// In Rust, we would ideally like to model this data as a pair of `Player`
33/// structs, rather than repeating the fields of `Player` for each prefix.
34///
35/// ```rust
36/// # #[allow(dead_code)]
37/// struct Match {
38///     player1: Player,
39///     player2: Player,
40/// }
41///
42/// # #[allow(dead_code)]
43/// struct Player {
44///     name: String,
45///     votes: u64,
46/// }
47/// ```
48///
49/// This `with_prefix!` macro produces an adapter that adds a prefix onto field
50/// names during serialization and trims away the prefix during deserialization.
51/// An implementation of the Challonge API would use `with_prefix!` like this:
52///
53/// ```rust
54/// use serde::{Deserialize, Serialize};
55/// use serde_with::with_prefix;
56///
57/// #[derive(Serialize, Deserialize)]
58/// struct Match {
59///     #[serde(flatten, with = "prefix_player1")]
60///     player1: Player,
61///     #[serde(flatten, with = "prefix_player2")]
62///     player2: Player,
63/// }
64///
65/// #[derive(Serialize, Deserialize)]
66/// struct Player {
67///     name: String,
68///     votes: u64,
69/// }
70///
71/// with_prefix!(prefix_player1 "player1_");
72/// // You can also set the visibility of the generated prefix module, the default is private.
73/// with_prefix!(pub prefix_player2 "player2_");
74/// #
75/// # const EXPECTED: &str = r#"{
76/// #   "player1_name": "name1",
77/// #   "player1_votes": 1,
78/// #   "player2_name": "name2",
79/// #   "player2_votes": 2
80/// # }"#;
81///
82/// fn main() {
83///     let m = Match {
84///         player1: Player {
85///             name: "name1".to_owned(),
86///             votes: 1,
87///         },
88///         player2: Player {
89///             name: "name2".to_owned(),
90///             votes: 2,
91///         },
92///     };
93///
94///     let j = serde_json::to_string_pretty(&m).unwrap();
95///     println!("{}", j);
96/// #
97/// #     assert_eq!(j, EXPECTED);
98/// }
99/// ```
100///
101/// [`deny_unknown_fields`]: https://serde.rs/container-attrs.html#deny_unknown_fields
102/// [issue-with_prefix-deny_unknown_fields]: https://github.com/jonasbb/serde_with/issues/57
103#[macro_export]
104macro_rules! with_prefix {
105    ($module:ident $prefix:expr) => {$crate::with_prefix!(pub(self) $module $prefix);};
106    ($vis:vis $module:ident $prefix:expr) => {
107        $vis mod $module {
108            use $crate::serde::{Deserialize, Deserializer, Serialize, Serializer};
109            use $crate::with_prefix::WithPrefix;
110
111            #[allow(dead_code)]
112            pub fn serialize<T, S>(object: &T, serializer: S) -> $crate::__private__::Result<S::Ok, S::Error>
113            where
114                T: Serialize,
115                S: Serializer,
116            {
117                object.serialize(WithPrefix {
118                    delegate: serializer,
119                    prefix: $prefix,
120                })
121            }
122
123            #[allow(dead_code)]
124            pub fn deserialize<'de, T, D>(deserializer: D) -> $crate::__private__::Result<T, D::Error>
125            where
126                T: Deserialize<'de>,
127                D: Deserializer<'de>,
128            {
129                T::deserialize(WithPrefix {
130                    delegate: deserializer,
131                    prefix: $prefix,
132                })
133            }
134        }
135    };
136}
137
138pub struct WithPrefix<'a, T> {
139    pub delegate: T,
140    pub prefix: &'a str,
141}
142
143impl<T> Serialize for WithPrefix<'_, T>
144where
145    T: Serialize,
146{
147    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
148    where
149        S: Serializer,
150    {
151        self.delegate.serialize(WithPrefix {
152            delegate: serializer,
153            prefix: self.prefix,
154        })
155    }
156}
157
158impl<'a, S> Serializer for WithPrefix<'a, S>
159where
160    S: Serializer,
161{
162    type Ok = S::Ok;
163    type Error = S::Error;
164    type SerializeSeq = Impossible<Self::Ok, Self::Error>;
165    type SerializeTuple = Impossible<Self::Ok, Self::Error>;
166    type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
167    type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
168    type SerializeMap = WithPrefix<'a, S::SerializeMap>;
169    type SerializeStruct = WithPrefix<'a, S::SerializeMap>;
170    type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;
171
172    fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
173        Err(SerError::custom("wrong type for with_prefix"))
174    }
175
176    fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
177        Err(SerError::custom("wrong type for with_prefix"))
178    }
179
180    fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
181        Err(SerError::custom("wrong type for with_prefix"))
182    }
183
184    fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
185        Err(SerError::custom("wrong type for with_prefix"))
186    }
187
188    fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
189        Err(SerError::custom("wrong type for with_prefix"))
190    }
191
192    fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
193        Err(SerError::custom("wrong type for with_prefix"))
194    }
195
196    fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
197        Err(SerError::custom("wrong type for with_prefix"))
198    }
199
200    fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
201        Err(SerError::custom("wrong type for with_prefix"))
202    }
203
204    fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
205        Err(SerError::custom("wrong type for with_prefix"))
206    }
207
208    fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
209        Err(SerError::custom("wrong type for with_prefix"))
210    }
211
212    fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
213        Err(SerError::custom("wrong type for with_prefix"))
214    }
215
216    fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
217        Err(SerError::custom("wrong type for with_prefix"))
218    }
219
220    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
221        self.delegate
222            .collect_str(&format_args!("{}{}", self.prefix, v))
223    }
224
225    fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
226        Err(SerError::custom("wrong type for with_prefix"))
227    }
228
229    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
230        self.delegate.serialize_none()
231    }
232
233    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
234    where
235        T: ?Sized + Serialize,
236    {
237        self.delegate.serialize_some(&WithPrefix {
238            delegate: value,
239            prefix: self.prefix,
240        })
241    }
242
243    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
244        Err(SerError::custom("wrong type for with_prefix"))
245    }
246
247    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
248        Err(SerError::custom("wrong type for with_prefix"))
249    }
250
251    fn serialize_unit_variant(
252        self,
253        _name: &'static str,
254        _variant_index: u32,
255        variant: &'static str,
256    ) -> Result<Self::Ok, Self::Error> {
257        self.serialize_str(variant)
258    }
259
260    fn serialize_newtype_struct<T>(
261        self,
262        _name: &'static str,
263        _value: &T,
264    ) -> Result<Self::Ok, Self::Error>
265    where
266        T: ?Sized + Serialize,
267    {
268        Err(SerError::custom("wrong type for with_prefix"))
269    }
270
271    fn serialize_newtype_variant<T>(
272        self,
273        _name: &'static str,
274        _variant_index: u32,
275        _variant: &'static str,
276        _value: &T,
277    ) -> Result<Self::Ok, Self::Error>
278    where
279        T: ?Sized + Serialize,
280    {
281        Err(SerError::custom("wrong type for with_prefix"))
282    }
283
284    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
285        Err(SerError::custom("wrong type for with_prefix"))
286    }
287
288    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
289        Err(SerError::custom("wrong type for with_prefix"))
290    }
291
292    fn serialize_tuple_struct(
293        self,
294        _name: &'static str,
295        _len: usize,
296    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
297        Err(SerError::custom("wrong type for with_prefix"))
298    }
299
300    fn serialize_tuple_variant(
301        self,
302        _name: &'static str,
303        _variant_index: u32,
304        _variant: &'static str,
305        _len: usize,
306    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
307        Err(SerError::custom("wrong type for with_prefix"))
308    }
309
310    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
311        Ok(WithPrefix {
312            delegate: self.delegate.serialize_map(len)?,
313            prefix: self.prefix,
314        })
315    }
316
317    fn serialize_struct(
318        self,
319        _name: &'static str,
320        len: usize,
321    ) -> Result<Self::SerializeStruct, Self::Error> {
322        self.serialize_map(Some(len))
323    }
324
325    fn serialize_struct_variant(
326        self,
327        _name: &'static str,
328        _variant_index: u32,
329        _variant: &'static str,
330        _len: usize,
331    ) -> Result<Self::SerializeStructVariant, Self::Error> {
332        Err(SerError::custom("wrong type for with_prefix"))
333    }
334}
335
336impl<S> SerializeMap for WithPrefix<'_, S>
337where
338    S: SerializeMap,
339{
340    type Ok = S::Ok;
341    type Error = S::Error;
342
343    fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
344    where
345        T: ?Sized + Serialize,
346    {
347        self.delegate.serialize_key(&WithPrefix {
348            delegate: key,
349            prefix: self.prefix,
350        })
351    }
352
353    fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
354    where
355        T: ?Sized + Serialize,
356    {
357        self.delegate.serialize_value(value)
358    }
359
360    fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<(), Self::Error>
361    where
362        K: ?Sized + Serialize,
363        V: ?Sized + Serialize,
364    {
365        self.delegate.serialize_entry(
366            &WithPrefix {
367                delegate: key,
368                prefix: self.prefix,
369            },
370            value,
371        )
372    }
373
374    fn end(self) -> Result<Self::Ok, Self::Error> {
375        self.delegate.end()
376    }
377}
378
379impl<S> SerializeStruct for WithPrefix<'_, S>
380where
381    S: SerializeMap,
382{
383    type Ok = S::Ok;
384    type Error = S::Error;
385
386    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
387    where
388        T: ?Sized + Serialize,
389    {
390        let mut prefixed_key = String::with_capacity(self.prefix.len() + key.len());
391        prefixed_key.push_str(self.prefix);
392        prefixed_key.push_str(key);
393        self.delegate.serialize_entry(&prefixed_key, value)
394    }
395
396    fn end(self) -> Result<Self::Ok, Self::Error> {
397        self.delegate.end()
398    }
399}
400
401impl<'de, T> DeserializeSeed<'de> for WithPrefix<'_, T>
402where
403    T: DeserializeSeed<'de>,
404{
405    type Value = T::Value;
406
407    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
408    where
409        D: Deserializer<'de>,
410    {
411        self.delegate.deserialize(WithPrefix {
412            delegate: deserializer,
413            prefix: self.prefix,
414        })
415    }
416}
417
418impl<'de, D> Deserializer<'de> for WithPrefix<'_, D>
419where
420    D: Deserializer<'de>,
421{
422    type Error = D::Error;
423
424    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
425    where
426        V: Visitor<'de>,
427    {
428        self.delegate.deserialize_map(WithPrefix {
429            delegate: visitor,
430            prefix: self.prefix,
431        })
432    }
433
434    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
435    where
436        V: Visitor<'de>,
437    {
438        self.delegate.deserialize_any(WithPrefixOption {
439            first_key: None,
440            delegate: visitor,
441            prefix: self.prefix,
442        })
443    }
444
445    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
446    where
447        V: Visitor<'de>,
448    {
449        self.delegate.deserialize_identifier(WithPrefix {
450            delegate: visitor,
451            prefix: self.prefix,
452        })
453    }
454
455    forward_to_deserialize_any! {
456        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
457        bytes byte_buf unit unit_struct newtype_struct seq tuple tuple_struct
458        map struct enum ignored_any
459    }
460}
461
462impl<'de, V> Visitor<'de> for WithPrefix<'_, V>
463where
464    V: Visitor<'de>,
465{
466    type Value = V::Value;
467
468    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
469        self.delegate.expecting(formatter)
470    }
471
472    fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
473    where
474        A: MapAccess<'de>,
475    {
476        self.delegate.visit_map(WithPrefix {
477            delegate: map,
478            prefix: self.prefix,
479        })
480    }
481}
482
483impl<'de, A> MapAccess<'de> for WithPrefix<'_, A>
484where
485    A: MapAccess<'de>,
486{
487    type Error = A::Error;
488
489    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
490    where
491        K: DeserializeSeed<'de>,
492    {
493        while let Some(s) = self.delegate.next_key::<String>()? {
494            if let Some(without_prefix) = s.strip_prefix(self.prefix) {
495                return seed
496                    .deserialize(without_prefix.into_deserializer())
497                    .map(Some);
498            }
499            self.delegate.next_value::<IgnoredAny>()?;
500        }
501        Ok(None)
502    }
503
504    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
505    where
506        V: DeserializeSeed<'de>,
507    {
508        self.delegate.next_value_seed(seed)
509    }
510}
511
512pub struct WithPrefixOption<'a, T> {
513    first_key: Option<String>,
514    delegate: T,
515    prefix: &'a str,
516}
517
518impl<'de, V> Visitor<'de> for WithPrefixOption<'_, V>
519where
520    V: Visitor<'de>,
521{
522    type Value = V::Value;
523
524    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
525        self.delegate.expecting(formatter)
526    }
527
528    fn visit_unit<E>(self) -> Result<Self::Value, E>
529    where
530        E: DeError,
531    {
532        self.delegate.visit_none()
533    }
534
535    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
536    where
537        A: MapAccess<'de>,
538    {
539        while let Some(s) = map.next_key::<String>()? {
540            if s.starts_with(self.prefix) {
541                return self.delegate.visit_some(WithPrefixOption {
542                    first_key: Some(s),
543                    delegate: map,
544                    prefix: self.prefix,
545                });
546            }
547            map.next_value::<IgnoredAny>()?;
548        }
549        self.delegate.visit_none()
550    }
551}
552
553impl<'de, A> Deserializer<'de> for WithPrefixOption<'_, A>
554where
555    A: MapAccess<'de>,
556{
557    type Error = A::Error;
558
559    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
560    where
561        V: Visitor<'de>,
562    {
563        visitor.visit_map(self)
564    }
565
566    forward_to_deserialize_any! {
567        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
568        bytes byte_buf option unit unit_struct newtype_struct seq tuple
569        tuple_struct map struct enum identifier ignored_any
570    }
571}
572
573impl<'de, A> MapAccess<'de> for WithPrefixOption<'_, A>
574where
575    A: MapAccess<'de>,
576{
577    type Error = A::Error;
578
579    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
580    where
581        K: DeserializeSeed<'de>,
582    {
583        if let Some(s) = self.first_key.take() {
584            let without_prefix = s[self.prefix.len()..].into_deserializer();
585            return seed.deserialize(without_prefix).map(Some);
586        }
587        while let Some(s) = self.delegate.next_key::<String>()? {
588            if let Some(without_prefix) = s.strip_prefix(self.prefix) {
589                return seed
590                    .deserialize(without_prefix.into_deserializer())
591                    .map(Some);
592            }
593            self.delegate.next_value::<IgnoredAny>()?;
594        }
595        Ok(None)
596    }
597
598    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
599    where
600        V: DeserializeSeed<'de>,
601    {
602        self.delegate.next_value_seed(seed)
603    }
604}