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
344fn 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}