Skip to main content

json_steroids/
traits.rs

1//! Serialization and deserialization traits
2//!
3//! These traits are implemented for primitive types and can be derived
4//! for custom structs and enums using the derive macros.
5
6use crate::error::Result;
7use crate::parser::{JsonParser, ParseInt};
8use crate::writer::{JsonWriter, Writer};
9use std::borrow::Cow;
10use std::collections::{BTreeMap, HashMap};
11use std::hash::Hash;
12
13/// Trait for types that can be serialized to JSON
14pub trait JsonSerialize {
15    /// Serialize this value to the given writer
16    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>);
17}
18
19/// Trait for types that can be deserialized from JSON
20///
21/// The lifetime parameter `'de` represents the lifetime of the data being deserialized,
22/// which allows for zero-copy deserialization when possible.
23pub trait JsonDeserialize<'de>: Sized {
24    /// Deserialize a value from the given parser
25    fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self>;
26}
27
28// ============ Primitive implementations ============
29
30impl JsonSerialize for bool {
31    #[inline]
32    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
33        writer.write_bool(*self);
34    }
35}
36
37impl<'de> JsonDeserialize<'de> for bool {
38    #[inline]
39    fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self> {
40        parser.parse_bool()
41    }
42}
43
44// Signed integers
45macro_rules! impl_json_signed {
46    ($($ty:ty, $write_method:ident),*) => {
47        $(
48            impl JsonSerialize for $ty {
49                #[inline]
50                fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
51                    writer.$write_method(*self);
52                }
53            }
54
55            impl<'de> JsonDeserialize<'de> for $ty {
56                #[inline]
57                fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self>
58                where Self: ParseInt {
59                    parser.parse_integer::<Self>()
60                }
61            }
62        )*
63    };
64}
65
66impl_json_signed!(
67    i8,
68    write_i8,
69    i16,
70    write_i16,
71    i32,
72    write_i32,
73    i64,
74    write_i64,
75    isize,
76    write_isize
77);
78
79// Unsigned integers
80macro_rules! impl_json_unsigned {
81    ($($ty:ty, $write_method:ident),*) => {
82        $(
83            impl JsonSerialize for $ty {
84                #[inline]
85                fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
86                    writer.$write_method(*self);
87                }
88            }
89
90            impl<'de> JsonDeserialize<'de> for $ty {
91                #[inline]
92                fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self>
93                where Self: ParseInt {
94                    parser.parse_integer::<Self>()
95                }
96            }
97        )*
98    };
99}
100
101impl_json_unsigned!(
102    u8,
103    write_u8,
104    u16,
105    write_u16,
106    u32,
107    write_u32,
108    u64,
109    write_u64,
110    usize,
111    write_usize
112);
113
114// Floats
115macro_rules! impl_json_float {
116    ($($ty:ty, $write_method:ident),*) => {
117        $(
118            impl JsonSerialize for $ty {
119                #[inline]
120                fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
121                    writer.$write_method(*self);
122                }
123            }
124
125            impl<'de> JsonDeserialize<'de> for $ty {
126                #[inline]
127                fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self> {
128                    parser.parse_float()
129                }
130            }
131        )*
132    };
133}
134
135impl_json_float!(f32, write_f32, f64, write_f64);
136
137// String types
138impl JsonSerialize for String {
139    #[inline]
140    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
141        writer.write_string(self);
142    }
143}
144
145impl<'de> JsonDeserialize<'de> for String {
146    #[inline]
147    fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self> {
148        parser.parse_string().map(|s| s.into_owned())
149    }
150}
151
152impl JsonSerialize for str {
153    #[inline]
154    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
155        writer.write_string(self);
156    }
157}
158
159impl<'a> JsonSerialize for Cow<'a, str> {
160    #[inline]
161    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
162        writer.write_string(self);
163    }
164}
165
166impl<'de> JsonDeserialize<'de> for Cow<'de, str> {
167    #[inline]
168    fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self> {
169        parser.parse_string()
170    }
171}
172
173impl<'de> JsonDeserialize<'de> for &'de str {
174    #[inline]
175    fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self> {
176        match parser.parse_string()? {
177            Cow::Borrowed(s) => Ok(s),
178            Cow::Owned(_) => {
179                // If the string contains escapes and needs to be owned,
180                // we can't return a borrowed &str. This is a limitation of zero-copy deserialization.
181                // In practice, this means &str deserialization only works with strings without escapes.
182                // For a more flexible approach, use Cow<'de, str> instead.
183                Err(crate::error::JsonError::Custom(
184                    "Cannot deserialize &str from string with escape sequences. Use Cow<'de, str> or String instead.".into()
185                ))
186            }
187        }
188    }
189}
190
191// Option
192impl<T: JsonSerialize> JsonSerialize for Option<T> {
193    #[inline]
194    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
195        match self {
196            Some(value) => value.json_serialize(writer),
197            None => writer.write_null(),
198        }
199    }
200}
201
202impl<'de, T: JsonDeserialize<'de>> JsonDeserialize<'de> for Option<T> {
203    #[inline]
204    fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self> {
205        parser.skip_whitespace_pub();
206        if parser.peek_is_null() {
207            parser.expect_null()?;
208            Ok(None)
209        } else {
210            T::json_deserialize(parser).map(Some)
211        }
212    }
213}
214
215// Vec
216impl<T: JsonSerialize> JsonSerialize for Vec<T> {
217    #[inline]
218    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
219        writer.begin_array();
220
221        let mut iter = self.iter();
222        if let Some(first) = iter.next() {
223            first.json_serialize(writer);
224
225            // Rest of elements with comma prefix
226            for item in iter {
227                writer.write_comma();
228                item.json_serialize(writer);
229            }
230        }
231
232        writer.end_array();
233    }
234}
235
236impl<'de, T: JsonDeserialize<'de>> JsonDeserialize<'de> for Vec<T> {
237    #[inline]
238    fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self> {
239        parser.expect_array_start()?;
240        // Start with a reasonable capacity to avoid repeated reallocations
241        let mut result = Vec::with_capacity(128);
242
243        let mut first = true;
244        loop {
245            if !parser.has_next_array_element_or_first(first)? {
246                break;
247            }
248            first = false;
249            result.push(T::json_deserialize(parser)?);
250        }
251
252        parser.expect_array_end()?;
253        Ok(result)
254    }
255}
256
257// Slice (serialize only)
258impl<T: JsonSerialize> JsonSerialize for [T] {
259    #[inline]
260    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
261        writer.begin_array();
262
263        // Handle first element separately to avoid conditional in hot loop
264        let mut iter = self.iter();
265        if let Some(first) = iter.next() {
266            first.json_serialize(writer);
267
268            // Rest of elements with comma prefix
269            for item in iter {
270                writer.write_comma();
271                item.json_serialize(writer);
272            }
273        }
274
275        writer.end_array();
276    }
277}
278
279// Arrays
280impl<T: JsonSerialize, const N: usize> JsonSerialize for [T; N] {
281    #[inline]
282    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
283        writer.begin_array();
284
285        // Handle first element separately to avoid conditional in hot loop
286        let mut iter = self.iter();
287        if let Some(first) = iter.next() {
288            first.json_serialize(writer);
289
290            // Rest of elements with comma prefix
291            for item in iter {
292                writer.write_comma();
293                item.json_serialize(writer);
294            }
295        }
296
297        writer.end_array();
298    }
299}
300
301// HashMap
302impl<K: AsRef<str>, V: JsonSerialize> JsonSerialize for HashMap<K, V> {
303    #[inline]
304    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
305        writer.begin_object();
306        for (i, (key, value)) in self.iter().enumerate() {
307            if i > 0 {
308                writer.write_comma();
309            }
310            writer.write_key(key.as_ref());
311            value.json_serialize(writer);
312        }
313        writer.end_object();
314    }
315}
316
317impl<'de, K, V> JsonDeserialize<'de> for HashMap<K, V>
318where
319    K: From<String> + Eq + Hash,
320    V: JsonDeserialize<'de>,
321{
322    #[inline]
323    fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self> {
324        parser.expect_object_start()?;
325        let mut result = HashMap::new();
326
327        while let Some(key) = parser.next_object_key()? {
328            let value = V::json_deserialize(parser)?;
329            result.insert(K::from(key.into_owned()), value);
330        }
331
332        Ok(result)
333    }
334}
335
336// BTreeMap
337impl<K: AsRef<str>, V: JsonSerialize> JsonSerialize for BTreeMap<K, V> {
338    #[inline]
339    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
340        writer.begin_object();
341        for (i, (key, value)) in self.iter().enumerate() {
342            if i > 0 {
343                writer.write_comma();
344            }
345            writer.write_key(key.as_ref());
346            value.json_serialize(writer);
347        }
348        writer.end_object();
349    }
350}
351
352impl<'de, K, V> JsonDeserialize<'de> for BTreeMap<K, V>
353where
354    K: From<String> + Ord,
355    V: JsonDeserialize<'de>,
356{
357    #[inline]
358    fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self> {
359        parser.expect_object_start()?;
360        let mut result = BTreeMap::new();
361
362        while let Some(key) = parser.next_object_key()? {
363            let value = V::json_deserialize(parser)?;
364            result.insert(K::from(key.into_owned()), value);
365        }
366
367        Ok(result)
368    }
369}
370
371// Box
372impl<T: JsonSerialize + ?Sized> JsonSerialize for Box<T> {
373    #[inline]
374    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
375        (**self).json_serialize(writer);
376    }
377}
378
379impl<'de, T: JsonDeserialize<'de>> JsonDeserialize<'de> for Box<T> {
380    #[inline]
381    fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self> {
382        T::json_deserialize(parser).map(Box::new)
383    }
384}
385
386// References (serialize only) - blanket impl for all references
387impl<T: JsonSerialize + ?Sized> JsonSerialize for &T {
388    #[inline]
389    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
390        (**self).json_serialize(writer);
391    }
392}
393
394impl<T: JsonSerialize + ?Sized> JsonSerialize for &mut T {
395    #[inline]
396    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
397        (**self).json_serialize(writer);
398    }
399}
400
401// Unit type
402impl JsonSerialize for () {
403    #[inline]
404    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
405        writer.write_null();
406    }
407}
408
409impl<'de> JsonDeserialize<'de> for () {
410    #[inline]
411    fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self> {
412        parser.expect_null()?;
413        Ok(())
414    }
415}
416
417// Tuples
418macro_rules! impl_tuple {
419    ($($idx:tt $T:ident),+) => {
420        impl<$($T: JsonSerialize),+> JsonSerialize for ($($T,)+) {
421            #[inline]
422            #[allow(unused_assignments)]
423            fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
424                writer.begin_array();
425                let mut first = true;
426                $(
427                    if !first {
428                        writer.write_comma();
429                    }
430                    first = false;
431                    self.$idx.json_serialize(writer);
432                )+
433                writer.end_array();
434            }
435        }
436
437        impl<'de, $($T: JsonDeserialize<'de>),+> JsonDeserialize<'de> for ($($T,)+) {
438            #[inline]
439            fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self> {
440                parser.expect_array_start()?;
441                let result = ($(
442                    {
443                        if $idx > 0 {
444                            parser.expect_comma()?;
445                        }
446                        $T::json_deserialize(parser)?
447                    },
448                )+);
449                parser.expect_array_end()?;
450                Ok(result)
451            }
452        }
453    };
454}
455
456impl_tuple!(0 T0);
457impl_tuple!(0 T0, 1 T1);
458impl_tuple!(0 T0, 1 T1, 2 T2);
459impl_tuple!(0 T0, 1 T1, 2 T2, 3 T3);
460impl_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4);
461impl_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5);
462impl_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6);
463impl_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7);
464
465// JsonValue
466impl JsonSerialize for crate::JsonValue {
467    fn json_serialize<W: Writer>(&self, writer: &mut JsonWriter<W>) {
468        use crate::JsonValue;
469        match self {
470            JsonValue::Null => writer.write_null(),
471            JsonValue::Bool(b) => writer.write_bool(*b),
472            JsonValue::Integer(n) => writer.write_i64(*n),
473            JsonValue::Float(f) => writer.write_f64(*f),
474            JsonValue::String(s) => writer.write_string(s),
475            JsonValue::Array(arr) => {
476                writer.begin_array();
477                for (i, item) in arr.iter().enumerate() {
478                    if i > 0 {
479                        writer.write_comma();
480                    }
481                    item.json_serialize(writer);
482                }
483                writer.end_array();
484            }
485            JsonValue::Object(obj) => {
486                writer.begin_object();
487                for (i, (key, value)) in obj.iter().enumerate() {
488                    if i > 0 {
489                        writer.write_comma();
490                    }
491                    writer.write_key(key);
492                    value.json_serialize(writer);
493                }
494                writer.end_object();
495            }
496        }
497    }
498}
499
500impl<'de> JsonDeserialize<'de> for crate::JsonValue {
501    fn json_deserialize(parser: &mut JsonParser<'de>) -> Result<Self> {
502        parser.parse_value()
503    }
504}