serde_hooks/ser/wrapper/
serializer.rs

1use std::borrow::Cow;
2
3use serde::{Serialize, Serializer};
4
5use super::map::SerializeMapWrapper;
6use super::r#struct::SerializeStructWrapper;
7use super::seq::SerializeSeqWrapper;
8use super::{SerializableKind, SerializerWrapperHooks, ValueAction, VariantAction, VariantActions};
9use crate::Case;
10
11pub(crate) struct SerializerWrapper<'h, S, H: SerializerWrapperHooks> {
12    serializer: S,
13    hooks: &'h H,
14    kind: SerializableKind,
15}
16
17impl<'h, S: Serializer, H: SerializerWrapperHooks> SerializerWrapper<'h, S, H> {
18    pub(crate) fn new(serializer: S, hooks: &'h H, kind: SerializableKind) -> Self {
19        Self {
20            serializer,
21            hooks,
22            kind,
23        }
24    }
25}
26
27macro_rules! value_ctor {
28    ($variant:ident) => {
29        crate::Value::$variant
30    };
31    ($variant:ident, $arg:ident) => {
32        crate::Value::$variant($arg.into())
33    };
34    ($variant:ident, $arg0:ident $(, $arg:ident)+) => {
35        crate::Value::$variant{
36            $arg0 : $arg0.into(),
37            $($arg : $arg.into(),)*
38        }
39    };
40}
41
42macro_rules! on_value_callback {
43    ($self:ident $variant:ident $(, $arg:ident : $type:ty)*) => {
44        match $self.kind {
45            SerializableKind::Value => $self
46                .hooks
47                .on_value($self.serializer, value_ctor!($variant $(, $arg)*))?,
48            SerializableKind::MapKey => $self
49                .hooks
50                .on_map_key($self.serializer, value_ctor!($variant $(, $arg)*))?,
51        }
52    }
53}
54
55macro_rules! value_serialize {
56    ($fn:ident, $variant:ident $(, $arg:ident : $type:ty)* $(=> $v:ident : $vt:ident)?) => {
57        fn $fn $(<$vt>)? (self, $($arg: $type,)* $($v: &$vt)?) -> Result<Self::Ok, Self::Error>
58        $(where $vt: Serialize + ?Sized)?
59        {
60            let value_action = on_value_callback!(self $variant $(, $arg : $type)*);
61            match value_action {
62                ValueAction::ContinueSerialization(s) => s.$fn($($arg,)* $($v)?),
63                ValueAction::ValueReplaced(r) => r,
64            }
65        }
66    };
67}
68
69impl<'h, S: Serializer, H: SerializerWrapperHooks> Serializer for SerializerWrapper<'h, S, H> {
70    type Ok = S::Ok;
71    type Error = S::Error;
72    type SerializeSeq = SerializeSeqWrapper<'h, S, H>;
73    type SerializeTuple = SerializeSeqWrapper<'h, S, H>;
74    type SerializeTupleStruct = SerializeSeqWrapper<'h, S, H>;
75    type SerializeTupleVariant = SerializeSeqWrapper<'h, S, H>;
76    type SerializeMap = SerializeMapWrapper<'h, S, H>;
77    type SerializeStruct = SerializeStructWrapper<'h, S, H>;
78    type SerializeStructVariant = SerializeStructWrapper<'h, S, H>;
79
80    value_serialize!(serialize_bool, Bool, v: bool);
81    value_serialize!(serialize_i8, I8, v: i8);
82    value_serialize!(serialize_i16, I16, v: i16);
83    value_serialize!(serialize_i32, I32, v: i32);
84    value_serialize!(serialize_i64, I64, v: i64);
85    value_serialize!(serialize_i128, I128, v: i128);
86    value_serialize!(serialize_u8, U8, v: u8);
87    value_serialize!(serialize_u16, U16, v: u16);
88    value_serialize!(serialize_u32, U32, v: u32);
89    value_serialize!(serialize_u64, U64, v: u64);
90    value_serialize!(serialize_u128, U128, v: u128);
91    value_serialize!(serialize_f32, F32, v: f32);
92    value_serialize!(serialize_f64, F64, v: f64);
93    value_serialize!(serialize_char, Char, v: char);
94    value_serialize!(serialize_str, Str, v: &str);
95    value_serialize!(serialize_bytes, Bytes, v: &[u8]);
96    value_serialize!(serialize_unit, Unit);
97
98    value_serialize!(serialize_unit_struct, UnitStruct, name: &'static str);
99
100    fn serialize_unit_variant(
101        self,
102        name: &'static str,
103        variant_index: u32,
104        variant: &'static str,
105    ) -> Result<Self::Ok, Self::Error> {
106        let value_action = on_value_callback!(self UnitVariant,
107            name: &'static str,
108            variant_index: u32,
109            variant: &'static str
110        );
111
112        match value_action {
113            ValueAction::ValueReplaced(r) => r,
114            ValueAction::ContinueSerialization(s) => {
115                let variant_actions = self.hooks.on_unit_variant(name, variant, variant_index);
116                let (name, variant_index, variant) = apply_variant_actions(
117                    name,
118                    variant_index,
119                    variant,
120                    variant_actions,
121                    self.hooks,
122                );
123                s.serialize_unit_variant(name, variant_index, variant)
124            }
125        }
126    }
127
128    fn serialize_newtype_variant<T: ?Sized>(
129        self,
130        name: &'static str,
131        variant_index: u32,
132        variant: &'static str,
133        value: &T,
134    ) -> Result<Self::Ok, Self::Error>
135    where
136        T: Serialize,
137    {
138        let value_action = on_value_callback!(self NewtypeVariant,
139            name: &'static str,
140            variant_index: u32,
141            variant: &'static str
142        );
143
144        match value_action {
145            ValueAction::ValueReplaced(r) => r,
146            ValueAction::ContinueSerialization(s) => {
147                let variant_actions = self.hooks.on_newtype_variant(name, variant, variant_index);
148                let (name, variant_index, variant) = apply_variant_actions(
149                    name,
150                    variant_index,
151                    variant,
152                    variant_actions,
153                    self.hooks,
154                );
155                s.serialize_newtype_variant(name, variant_index, variant, value)
156            }
157        }
158    }
159
160    value_serialize!(
161        serialize_newtype_struct,
162        NewtypeStruct,
163        name: &'static str
164        =>
165        value: T
166    );
167
168    value_serialize!(serialize_none, None);
169    value_serialize!(
170        serialize_some,
171        Some
172        =>
173        value: T
174    );
175
176    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
177        let value_action = on_value_callback!(self Seq,
178            len: Option<usize>
179        );
180        match value_action {
181            ValueAction::ValueReplaced(r) => Ok(SerializeSeqWrapper::new_skipped(r)),
182            ValueAction::ContinueSerialization(s) => {
183                let actions = self.hooks.on_seq(len);
184                SerializeSeqWrapper::serialize_seq(s, len, self.hooks, actions)
185            }
186        }
187    }
188
189    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
190        let value_action = on_value_callback!(self Tuple,
191            len: usize
192        );
193        match value_action {
194            ValueAction::ValueReplaced(r) => Ok(SerializeSeqWrapper::new_skipped(r)),
195            ValueAction::ContinueSerialization(s) => {
196                let seq_actions = self.hooks.on_tuple(len);
197                SerializeSeqWrapper::serialize_tuple(s, len, self.hooks, seq_actions)
198            }
199        }
200    }
201
202    fn serialize_tuple_struct(
203        self,
204        name: &'static str,
205        len: usize,
206    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
207        let value_action = on_value_callback!(self TupleStruct,
208            name: &'static str,
209            len: usize
210        );
211        match value_action {
212            ValueAction::ValueReplaced(r) => Ok(SerializeSeqWrapper::new_skipped(r)),
213            ValueAction::ContinueSerialization(s) => {
214                let seq_actions = self.hooks.on_tuple_struct(name, len);
215                SerializeSeqWrapper::serialize_tuple_struct(s, name, len, self.hooks, seq_actions)
216            }
217        }
218    }
219
220    fn serialize_tuple_variant(
221        self,
222        name: &'static str,
223        variant_index: u32,
224        variant: &'static str,
225        len: usize,
226    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
227        let value_action = on_value_callback!(self TupleVariant,
228            name: &'static str,
229            variant_index: u32,
230            variant: &'static str,
231            len: usize
232        );
233
234        match value_action {
235            ValueAction::ValueReplaced(r) => Ok(SerializeSeqWrapper::new_skipped(r)),
236            ValueAction::ContinueSerialization(s) => {
237                let (variant_actions, seq_actions) =
238                    self.hooks
239                        .on_tuple_variant(name, variant_index, variant, len);
240
241                let (name, variant_index, variant) = apply_variant_actions(
242                    name,
243                    variant_index,
244                    variant,
245                    variant_actions,
246                    self.hooks,
247                );
248
249                SerializeSeqWrapper::serialize_tuple_variant(
250                    s,
251                    name,
252                    variant_index,
253                    variant,
254                    len,
255                    self.hooks,
256                    seq_actions,
257                )
258            }
259        }
260    }
261
262    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
263        let value_action = on_value_callback!(self Map,
264            len: Option<usize>
265        );
266        match value_action {
267            ValueAction::ValueReplaced(r) => Ok(SerializeMapWrapper::new_skipped(r)),
268            ValueAction::ContinueSerialization(s) => {
269                let actions = self.hooks.on_map(len);
270                SerializeMapWrapper::serialize_map(s, len, self.hooks, actions)
271            }
272        }
273    }
274
275    fn serialize_struct(
276        self,
277        name: &'static str,
278        len: usize,
279    ) -> Result<Self::SerializeStruct, Self::Error> {
280        let value_action = on_value_callback!(self Struct,
281            name: &'static str,
282            len: usize
283        );
284        match value_action {
285            ValueAction::ValueReplaced(r) => Ok(SerializeStructWrapper::new_skipped(r)),
286            ValueAction::ContinueSerialization(s) => {
287                let (struct_actions, field_actions) = self.hooks.on_struct(len, name);
288
289                SerializeStructWrapper::serialize_struct(
290                    s,
291                    name,
292                    len,
293                    self.hooks,
294                    struct_actions,
295                    field_actions,
296                )
297            }
298        }
299    }
300
301    fn serialize_struct_variant(
302        self,
303        name: &'static str,
304        variant_index: u32,
305        variant: &'static str,
306        len: usize,
307    ) -> Result<Self::SerializeStructVariant, Self::Error> {
308        let value_action = on_value_callback!(self StructVariant,
309            name: &'static str,
310            variant_index: u32,
311            variant: &'static str,
312            len: usize
313        );
314        match value_action {
315            ValueAction::ValueReplaced(r) => Ok(SerializeStructWrapper::new_skipped(r)),
316            ValueAction::ContinueSerialization(s) => {
317                let (variant_actions, struct_actions, field_actions) = self
318                    .hooks
319                    .on_struct_variant(len, name, variant, variant_index);
320
321                let (name, variant_index, variant) = apply_variant_actions(
322                    name,
323                    variant_index,
324                    variant,
325                    variant_actions,
326                    self.hooks,
327                );
328
329                SerializeStructWrapper::serialize_struct_variant(
330                    s,
331                    name,
332                    variant_index,
333                    variant,
334                    len,
335                    self.hooks,
336                    struct_actions,
337                    field_actions,
338                )
339            }
340        }
341    }
342}
343
344/// Applies variant actions and return (possibly) new enum name, variant index and variant name.
345fn apply_variant_actions(
346    name: &'static str,
347    variant_index: u32,
348    variant: &'static str,
349    actions: VariantActions,
350    hooks: &impl SerializerWrapperHooks,
351) -> (&'static str, u32, &'static str) {
352    let mut new_name: Option<Cow<'static, str>> = None;
353    let mut enum_case: Option<Case> = None;
354    let mut new_variant: Option<Cow<'static, str>> = None;
355    let mut variant_case: Option<Case> = None;
356    let mut new_variant_index: Option<u32> = None;
357
358    actions.into_iter().rev().for_each(|a| match a {
359        VariantAction::RenameEnumCase(c) => {
360            enum_case.get_or_insert(c);
361        }
362        VariantAction::RenameEnum(n) => {
363            new_name.get_or_insert(n);
364        }
365        VariantAction::RenameVariantCase(c) => {
366            variant_case.get_or_insert(c);
367        }
368        VariantAction::RenameVariant(n) => {
369            new_variant.get_or_insert(n);
370        }
371        VariantAction::ChangeVariantIndex(i) => {
372            new_variant_index.get_or_insert(i);
373        }
374    });
375
376    if new_name.is_none() {
377        if let Some(c) = enum_case {
378            new_name = Some(Case::string_to_case(name, c).into());
379        }
380    }
381
382    if new_variant.is_none() {
383        if let Some(c) = variant_case {
384            new_variant = Some(Case::string_to_case(variant, c).into());
385        }
386    }
387
388    (
389        hooks.make_static_str(new_name.unwrap_or(name.into())),
390        new_variant_index.unwrap_or(variant_index),
391        hooks.make_static_str(new_variant.unwrap_or(variant.into())),
392    )
393}