1#![deny(missing_docs)]
2#![deny(rustdoc::broken_intra_doc_links)]
3#![doc = include_str!("../README.md")]
4
5#[cfg(feature = "json")]
6pub use merde_json as json;
7
8#[cfg(feature = "yaml")]
9pub use merde_yaml as yaml;
10
11#[cfg(feature = "core")]
12pub use merde_core::*;
13
14#[doc(hidden)]
15#[cfg(feature = "deserialize")]
16#[macro_export]
17macro_rules! impl_deserialize {
18 (struct $struct_name:ident transparent) => {
20 #[automatically_derived]
21 impl<'s> $crate::Deserialize<'s> for $struct_name {
22 #[inline(always)]
23 async fn deserialize(__de: &mut dyn $crate::DynDeserializer<'s>) -> Result<Self, $crate::MerdeError<'s>> {
24 use $crate::DynDeserializerExt;
25
26 Ok(Self($crate::DynDeserializerExt::t(__de).await?))
27 }
28 }
29 };
30
31 (struct $struct_name:ident <$s:lifetime> transparent) => {
33 #[automatically_derived]
34 impl<$s> $crate::Deserialize<$s> for $struct_name<$s> {
35 #[inline(always)]
36 async fn deserialize(__de: &mut dyn $crate::DynDeserializer<'s>) -> Result<Self, $crate::MerdeError<'s>> {
37 Ok(Self($crate::DynDeserializerExt::t(__de).await?))
38 }
39 }
40 };
41
42 (struct $struct_name:ident { $($field:ident),* }) => {
44 $crate::impl_deserialize! {
45 struct $struct_name { $($field),* } via $crate::DefaultDeserOpinions
46 }
47 };
48 (struct $struct_name:ident { $($field:ident),* } via $opinions:expr) => {
49 #[automatically_derived]
50 impl<'s> $crate::Deserialize<'s> for $struct_name {
51 #[inline(always)]
52 async fn deserialize(__de: &mut dyn $crate::DynDeserializer<'s>) -> Result<Self, $crate::MerdeError<'s>> {
53 #![allow(unreachable_code)]
54 use $crate::{DynDeserializerExt, DeserOpinions};
55
56 let __opinions = $opinions;
57 __de.next().await?.into_map_start()?;
58
59 $(
60 let mut $field = $crate::none_of(|i: $struct_name| i.$field);
61 )*
62
63 loop {
64 match __de.next().await? {
65 $crate::Event::MapEnd => break,
66 $crate::Event::Str(__key) => {
67 let __key = __opinions.map_key_name(__key);
68 match __key.as_ref() {
69 $(stringify!($field) => {
70 $field = Some($crate::DynDeserializerExt::t(__de).await?);
71 })*
72 _ => {
73 if __opinions.deny_unknown_fields() {
74 return Err($crate::MerdeError::UnknownProperty(__key).into());
75 }
76 }
77 }
78 }
79 ev => {
80 return Err($crate::MerdeError::UnexpectedEvent {
81 got: $crate::EventType::from(&ev),
82 expected: &[$crate::EventType::Str, $crate::EventType::MapEnd],
83 help: Some(format!("While deserializing {}", stringify!($struct_name))),
84 }
85 .into())
86 }
87 }
88 }
89
90 Ok($struct_name {
91 $($field: {
92 if $field.is_none() {
93 let __slot = $crate::FieldSlot::new(&mut $field);
94 __opinions.default_field_value(stringify!($field), __slot);
95 }
96 $crate::Deserialize::from_option($field, stringify!($field).into())?
97 },)*
98 })
99 }
100 }
101 };
102
103 (struct $struct_name:ident <$lifetime:lifetime> { $($field:ident),* }) => {
105 $crate::impl_deserialize! {
106 struct $struct_name <$lifetime> { $($field),* } via $crate::DefaultDeserOpinions
107 }
108 };
109 (struct $struct_name:ident <$s:lifetime> { $($field:ident),* } via $opinions:expr) => {
110 #[automatically_derived]
111 impl<$s> $crate::Deserialize<$s> for $struct_name<$s> {
112 #[inline(always)]
113 async fn deserialize(__de: &mut dyn $crate::DynDeserializer<$s>) -> Result<Self, $crate::MerdeError<$s>> {
114 #![allow(unreachable_code)]
115 use $crate::DeserOpinions;
116
117 let __opinions = $opinions;
118 __de.next().await?.into_map_start()?;
119
120 $(
121 let mut $field = $crate::none_of(|i: $struct_name<$s>| i.$field);
122 )+
123
124 loop {
125 match __de.next().await? {
126 $crate::Event::MapEnd => break,
127 $crate::Event::Str(__key) => {
128 let __key = __opinions.map_key_name(__key);
129 match __key.as_ref() {
130 $(stringify!($field) => {
131 $field = Some($crate::DynDeserializerExt::t(__de).await?);
132 })*
133 _ => {
134 if __opinions.deny_unknown_fields() {
135 return Err($crate::MerdeError::UnknownProperty(__key).into());
136 }
137 }
138 }
139 }
140 ev => {
141 return Err($crate::MerdeError::UnexpectedEvent {
142 got: $crate::EventType::from(&ev),
143 expected: &[$crate::EventType::Str, $crate::EventType::MapEnd],
144 help: Some(format!("While deserializing {}", stringify!($struct_name))),
145 }
146 .into())
147 }
148 }
149 }
150
151 Ok($struct_name {
152 $($field: {
153 if $field.is_none() {
154 let __slot = $crate::FieldSlot::new(&mut $field);
155 __opinions.default_field_value(stringify!($field), __slot);
156 }
157 $crate::Deserialize::from_option($field, stringify!($field).into())?
158 },)+
159 })
160 }
161 }
162 };
163
164 (enum $enum_name:ident externally_tagged {
166 $($variant_str:literal => $variant:ident),* $(,)?
167 }) => {
168 #[automatically_derived]
169 impl<'s> $crate::Deserialize<'s> for $enum_name {
170 async fn deserialize(__de: &mut dyn $crate::DynDeserializer<'s>) -> Result<Self, $crate::MerdeError<'s>> {
171 #[allow(unused_imports)]
172 use $crate::MerdeError;
173
174 __de.next().await?.into_map_start()?;
175 let key = __de.next().await?.into_str()?;
176 match key.as_ref() {
177 $($variant_str => {
178 let value = $crate::DynDeserializerExt::t(__de).await?;
179 __de.next().await?.into_map_end()?;
180 Ok($enum_name::$variant(value))
181 },)*
182 _ => Err(MerdeError::UnknownProperty(key).into()),
183 }
184 }
185 }
186 };
187
188 (enum $enum_name:ident <$lifetime:lifetime> externally_tagged {
190 $($variant_str:literal => $variant:ident),* $(,)?
191 }) => {
192 #[automatically_derived]
193 impl<$lifetime> $crate::Deserialize<$lifetime> for $enum_name<$lifetime> {
194 #[inline(always)]
195 async fn deserialize(__de: &mut dyn $crate::DynDeserializer<$lifetime>) -> Result<Self, $crate::MerdeError<$lifetime>> {
196 #[allow(unused_imports)]
197 use $crate::{MerdeError, DynDeserializerExt};
198
199 __de.next().await?.into_map_start()?;
200 let key = __de.next().await?.into_str()?;
201 match key.as_ref() {
202 $($variant_str => {
203 let value = $crate::DynDeserializerExt::t(__de).await?;
204 __de.next().await?.into_map_end()?;
205 Ok($enum_name::$variant(value))
206 },)*
207 _ => Err(MerdeError::UnknownProperty(key).into()),
208 }
209 }
210 }
211 };
212
213 (enum $enum_name:ident string_like {
215 $($variant_str:literal => $variant:ident),* $(,)?
216 }) => {
217 #[automatically_derived]
218 impl<'s> $crate::Deserialize<'s> for $enum_name {
219 async fn deserialize(__de: &mut dyn $crate::DynDeserializer<'s>) -> Result<Self, $crate::MerdeError<'s>> {
220 #[allow(unused_imports)]
221 use $crate::MerdeError;
222 use $crate::DynDeserializerExt;
223
224 let s = __de.next().await?.into_str()?;
225 match s.as_ref() {
226 $($variant_str => Ok($enum_name::$variant),)*
227 _ => Err(MerdeError::UnknownProperty(s).into()),
228 }
229 }
230 }
231 };
232}
233
234#[doc(hidden)]
235#[cfg(not(feature = "deserialize"))]
236#[macro_export]
237macro_rules! impl_deserialize {
238 ($($tt:tt)*) => {};
239}
240
241#[doc(hidden)]
242#[macro_export]
243#[cfg(feature = "core")]
244macro_rules! impl_into_static {
245 (struct $struct_name:ident transparent) => {
247 #[automatically_derived]
248 impl $crate::IntoStatic for $struct_name {
249 type Output = $struct_name;
250
251 #[inline(always)]
252 fn into_static(self) -> Self::Output {
253 self
254 }
255 }
256 };
257
258 (struct $struct_name:ident <$lifetime:lifetime> transparent) => {
260 #[automatically_derived]
261 impl<$lifetime> $crate::IntoStatic for $struct_name<$lifetime> {
262 type Output = $struct_name<'static>;
263
264 #[inline(always)]
265 fn into_static(self) -> Self::Output {
266 $struct_name($crate::IntoStatic::into_static(self.0))
267 }
268 }
269 };
270
271 (struct $struct_name:ident { $($field:ident),* } $($rest:tt)*) => {
273 #[automatically_derived]
274 impl $crate::IntoStatic for $struct_name {
275 type Output = $struct_name;
276
277 #[inline(always)]
278 fn into_static(self) -> Self::Output {
279 self
280 }
281 }
282 };
283
284 (struct $struct_name:ident <$lifetime:lifetime> { $($field:ident),* } $($rest:tt)*) => {
286 #[automatically_derived]
287 impl<$lifetime> $crate::IntoStatic for $struct_name<$lifetime> {
288 type Output = $struct_name<'static>;
289
290 fn into_static(self) -> Self::Output {
291 #[allow(unused_imports)]
292 use $crate::IntoStatic;
293
294 $struct_name {
295 $($field: $crate::IntoStatic::into_static(self.$field),)+
296 }
297 }
298 }
299 };
300
301 (enum $enum_name:ident externally_tagged {
303 $($variant_str:literal => $variant:ident),* $(,)?
304 }) => {
305 #[automatically_derived]
306 impl $crate::IntoStatic for $enum_name {
307 type Output = $enum_name;
308
309 #[inline(always)]
310 fn into_static(self) -> Self::Output {
311 self
312 }
313 }
314 };
315
316 (enum $enum_name:ident <$lifetime:lifetime> externally_tagged {
318 $($variant_str:literal => $variant:ident),* $(,)?
319 }) => {
320 #[automatically_derived]
321 impl<$lifetime> $crate::IntoStatic for $enum_name<$lifetime> {
322 type Output = $enum_name<'static>;
323
324 #[inline(always)]
325 fn into_static(self) -> Self::Output {
326 match self {
327 $(
328 Self::$variant(value) => $enum_name::$variant(value.into_static()),
329 )+
330 }
331 }
332 }
333 };
334
335 (enum $enum_name:ident string_like {
337 $($variant_str:literal => $variant:ident),* $(,)?
338 }) => {
339 #[automatically_derived]
340 impl $crate::IntoStatic for $enum_name {
341 type Output = $enum_name;
342
343 #[inline(always)]
344 fn into_static(self) -> Self::Output {
345 self
346 }
347 }
348 };
349}
350
351#[doc(hidden)]
352#[macro_export]
353#[cfg(not(feature = "core"))]
354macro_rules! impl_into_static {
355 ($($tt:tt)*) => {};
356}
357
358#[doc(hidden)]
359#[macro_export]
360#[cfg(feature = "core")]
361macro_rules! impl_with_lifetime {
362 (struct $struct_name:ident transparent) => {
364 #[automatically_derived]
365 impl<'s> $crate::WithLifetime<'s> for $struct_name {
366 type Lifetimed = $struct_name;
367 }
368 };
369
370 (struct $struct_name:ident <$lifetime:lifetime> transparent) => {
372 #[automatically_derived]
373 impl<'s> $crate::WithLifetime<'s> for $struct_name<$lifetime> {
374 type Lifetimed = $struct_name<$lifetime>;
375 }
376 };
377
378 (struct $struct_name:ident { $($field:ident),* } $($rest:tt)*) => {
380 #[automatically_derived]
381 impl<'s> $crate::WithLifetime<'s> for $struct_name {
382 type Lifetimed = $struct_name;
383 }
384 };
385
386 (struct $struct_name:ident <$lifetime:lifetime> { $($field:ident),* } $($rest:tt)*) => {
388 #[automatically_derived]
389 impl<$lifetime, 'instantiated_lifetime> $crate::WithLifetime<'instantiated_lifetime>
390 for $struct_name<$lifetime>
391 {
392 type Lifetimed = $struct_name<'instantiated_lifetime>;
393 }
394 };
395
396 (enum $enum_name:ident externally_tagged {
398 $($variant_str:literal => $variant:ident),* $(,)?
399 }) => {
400 #[automatically_derived]
401 impl<'s> $crate::WithLifetime<'s> for $enum_name {
402 type Lifetimed = $enum_name;
403 }
404 };
405
406 (enum $enum_name:ident <$lifetime:lifetime> externally_tagged {
408 $($variant_str:literal => $variant:ident),* $(,)?
409 }) => {
410 #[automatically_derived]
411 impl<$lifetime, 'instantiated_lifetime> $crate::WithLifetime<'instantiated_lifetime>
412 for $enum_name<$lifetime>
413 {
414 type Lifetimed = $enum_name<'instantiated_lifetime>;
415 }
416 };
417
418 (enum $enum_name:ident string_like {
420 $($variant_str:literal => $variant:ident),* $(,)?
421 }) => {
422 #[automatically_derived]
423 impl<'s> $crate::WithLifetime<'s> for $enum_name {
424 type Lifetimed = $enum_name;
425 }
426 };
427}
428
429#[doc(hidden)]
430#[macro_export]
431#[cfg(not(feature = "core"))]
432macro_rules! impl_with_lifetime {
433 ($($tt:tt)*) => {};
434}
435
436#[doc(hidden)]
437#[macro_export]
438#[cfg(feature = "core")]
439macro_rules! impl_serialize {
440 (struct $struct_name:ident transparent) => {
442 #[automatically_derived]
443 impl $crate::Serialize for $struct_name {
444 #[allow(clippy::manual_async_fn)]
445 fn serialize<'fut>(
446 &'fut self,
447 serializer: &'fut mut dyn $crate::DynSerializer,
448 ) -> impl ::std::future::Future<Output = Result<(), $crate::MerdeError<'static>>> + 'fut {
449 async move {
450 $crate::Serialize::serialize(&self.0, serializer).await
451 }
452 }
453 }
454 };
455
456 (struct $struct_name:ident <$lifetime:lifetime> transparent) => {
458 #[automatically_derived]
459 impl<$lifetime> $crate::Serialize for $struct_name<$lifetime> {
460 #[allow(clippy::manual_async_fn)]
461 fn serialize<'fut>(
462 &'fut self,
463 serializer: &'fut mut dyn $crate::DynSerializer,
464 ) -> impl ::std::future::Future<Output = Result<(), $crate::MerdeError<'static>>> + 'fut {
465 async move {
466 $crate::Serialize::serialize(&self.0, serializer).await
467 }
468 }
469 }
470 };
471
472 (struct $struct_name:ident < $lifetime:lifetime > { $($field:ident),* }) => {
474 #[automatically_derived]
475 impl<$lifetime> $crate::Serialize for $struct_name<$lifetime> {
476 #[allow(clippy::manual_async_fn)]
477 fn serialize<'fut>(
478 &'fut self,
479 serializer: &'fut mut dyn $crate::DynSerializer,
480 ) -> impl ::std::future::Future<Output = Result<(), $crate::MerdeError<'static>>> + 'fut {
481 async move {
482 serializer
483 .write($crate::Event::MapStart($crate::MapStart {
484 size_hint: Some($crate::count_ident_tokens!($($field)*)),
485 }))
486 .await?;
487 $(
488 serializer.write($crate::Event::Str($crate::CowStr::Borrowed(stringify!($field)))).await?;
489 $crate::Serialize::serialize(&self.$field, serializer).await?;
490 )+
491 serializer.write($crate::Event::MapEnd).await
492 }
493 }
494 }
495 };
496
497 (struct $struct_name:ident { $($field:ident),* }) => {
499 #[automatically_derived]
500 impl $crate::Serialize for $struct_name {
501 #[allow(clippy::manual_async_fn)]
502 fn serialize<'fut>(
503 &'fut self,
504 serializer: &'fut mut dyn $crate::DynSerializer,
505 ) -> impl ::std::future::Future<Output = Result<(), $crate::MerdeError<'static>>> + 'fut {
506 async move {
507 serializer
508 .write($crate::Event::MapStart($crate::MapStart {
509 size_hint: Some($crate::count_ident_tokens!($($field)*)),
510 }))
511 .await?;
512 $(
513 serializer.write($crate::Event::Str($crate::CowStr::Borrowed(stringify!($field)))).await?;
514 $crate::Serialize::serialize(&self.$field, serializer).await?;
515 )*
516 serializer.write($crate::Event::MapEnd).await
517 }
518 }
519 }
520 };
521
522 (enum $enum_name:ident externally_tagged {
524 $($variant_str:literal => $variant:ident),* $(,)?
525 }) => {
526 #[automatically_derived]
527 impl $crate::Serialize for $enum_name {
528 #[allow(clippy::manual_async_fn)]
529 fn serialize<'fut>(
530 &'fut self,
531 serializer: &'fut mut dyn $crate::DynSerializer,
532 ) -> impl ::std::future::Future<Output = Result<(), $crate::MerdeError<'static>>> + 'fut {
533 async move {
534 serializer
535 .write($crate::Event::MapStart($crate::MapStart {
536 size_hint: Some(1),
537 }))
538 .await?;
539
540 match self {
541 $(
542 Self::$variant(value) => {
543 serializer.write($crate::Event::Str($crate::CowStr::Borrowed($variant_str))).await?;
544 $crate::Serialize::serialize(value, serializer).await?;
545 }
546 )*
547 }
548
549 serializer.write($crate::Event::MapEnd).await
550 }
551 }
552 }
553 };
554
555 (enum $enum_name:ident <$lifetime:lifetime> externally_tagged {
557 $($variant_str:literal => $variant:ident),* $(,)?
558 }) => {
559 #[automatically_derived]
560 impl<$lifetime> $crate::Serialize for $enum_name<$lifetime> {
561 #[allow(clippy::manual_async_fn)]
562 fn serialize<'fut>(
563 &'fut self,
564 serializer: &'fut mut dyn $crate::DynSerializer,
565 ) -> impl ::std::future::Future<Output = Result<(), $crate::MerdeError<'static>>> + 'fut {
566 async move {
567 serializer
568 .write($crate::Event::MapStart($crate::MapStart {
569 size_hint: Some(1),
570 }))
571 .await?;
572
573 match self {
574 $(
575 Self::$variant(value) => {
576 serializer.write($crate::Event::Str($crate::CowStr::Borrowed($variant_str))).await?;
577 $crate::Serialize::serialize(value, serializer).await?;
578 }
579 )+
580 }
581
582 serializer.write($crate::Event::MapEnd).await
583 }
584 }
585 }
586 };
587
588 (enum $enum_name:ident string_like {
590 $($variant_str:literal => $variant:ident),* $(,)?
591 }) => {
592 #[automatically_derived]
593 impl $crate::Serialize for $enum_name {
594 #[allow(clippy::manual_async_fn)]
595 fn serialize<'fut>(
596 &'fut self,
597 serializer: &'fut mut dyn $crate::DynSerializer,
598 ) -> impl ::std::future::Future<Output = Result<(), $crate::MerdeError<'static>>> + 'fut {
599 async move {
600 match self {
601 $(
602 Self::$variant => {
603 serializer.write($crate::Event::Str($crate::CowStr::Borrowed($variant_str))).await
604 }
605 )+
606 }
607 }
608 }
609 }
610 };
611}
612
613#[doc(hidden)]
614#[macro_export]
615#[cfg(not(feature = "core"))]
616macro_rules! impl_serialize {
617 ($($rest:tt)*) => {};
618}
619
620#[doc(hidden)]
621#[macro_export]
622macro_rules! impl_trait {
623 (Deserialize for $($rest:tt)*) => {
625 $crate::impl_deserialize!($($rest)*);
626 $crate::impl_into_static!($($rest)*);
627 $crate::impl_with_lifetime!($($rest)*);
628 };
629
630 (Serialize for $($rest:tt)*) => {
631 $crate::impl_serialize!($($rest)*);
632 };
633}
634
635#[macro_export]
722macro_rules! derive {
723 (impl ($first_trait:ident, $($rest_traits:ident),*) for $($rest:tt)*) => {
725 $crate::impl_trait!($first_trait for $($rest)*);
726 $crate::derive!(impl ($($rest_traits),*) for $($rest)*);
727 };
728 (impl ($first_trait:ident) for $($rest:tt)*) => {
729 $crate::impl_trait!($first_trait for $($rest)*);
730 };
731 (impl () for $($rest:tt)*) => {};
732}
733
734#[doc(hidden)]
738pub fn none_of<I, T>(_f: impl FnOnce(I) -> T) -> Option<T> {
739 None
740}
741
742#[doc(hidden)]
743#[macro_export]
744macro_rules! count_ident_tokens {
745 () => { 0 };
746 ($first:ident) => { 1 };
747 ($first:ident $($rest:ident)*) => {
748 1 + $crate::count_ident_tokens!($($rest)*)
749 };
750}
751#[cfg(test)]
752#[cfg(feature = "json")]
753mod json_tests {
754 use std::collections::HashMap;
755
756 use super::*;
757 use crate::json::from_str;
758
759 #[test]
760 fn test_complex_structs() {
761 use std::borrow::Cow;
762 use std::collections::HashMap;
763
764 #[derive(Debug, PartialEq)]
765 struct SecondStruct<'s> {
766 string_field: Cow<'s, str>,
767 int_field: i32,
768 }
769
770 derive! {
771 impl (Serialize, Deserialize) for struct SecondStruct<'s> {
772 string_field,
773 int_field
774 }
775 }
776
777 #[derive(Debug, PartialEq)]
778 struct ComplexStruct<'s> {
779 string_field: Cow<'s, str>,
780 u8_field: u8,
781 u16_field: u16,
782 u32_field: u32,
783 u64_field: u64,
784 i8_field: i8,
785 i16_field: i16,
786 i32_field: i32,
787 i64_field: i64,
788 usize_field: usize,
789 bool_field: bool,
790 option_field: Option<i32>,
791 vec_field: Vec<i32>,
792 hashmap_field: HashMap<String, i32>,
793 second_struct_field: SecondStruct<'s>,
794 }
795
796 derive! {
797 impl (Serialize, Deserialize) for struct ComplexStruct<'s> {
798 string_field,
799 u8_field,
800 u16_field,
801 u32_field,
802 u64_field,
803 i8_field,
804 i16_field,
805 i32_field,
806 i64_field,
807 usize_field,
808 bool_field,
809 option_field,
810 vec_field,
811 hashmap_field,
812 second_struct_field
813 }
814 }
815
816 let mut hashmap = HashMap::new();
817 hashmap.insert("key".to_string(), 42);
818
819 let original = ComplexStruct {
820 string_field: Cow::Borrowed("test string"),
821 u8_field: 8,
822 u16_field: 16,
823 u32_field: 32,
824 u64_field: 64,
825 i8_field: -8,
826 i16_field: -16,
827 i32_field: -32,
828 i64_field: -64,
829 usize_field: 100,
830 bool_field: true,
831 option_field: Some(42),
832 vec_field: vec![1, 2, 3],
833 hashmap_field: hashmap,
834 second_struct_field: SecondStruct {
835 string_field: Cow::Borrowed("nested string"),
836 int_field: 100,
837 },
838 };
839
840 let serialized = crate::json::to_string(&original).unwrap();
841 let deserialized: ComplexStruct = from_str(&serialized).unwrap();
842
843 assert_eq!(original, deserialized);
844 }
845
846 #[test]
847 fn test_u8_zero() {
848 let original: u8 = 0;
849 let serialized = crate::json::to_string(&original).unwrap();
850 let deserialized: u8 = from_str(&serialized).unwrap();
851 assert_eq!(original, deserialized);
852 }
853
854 #[test]
855 fn test_u8_max() {
856 let original: u8 = u8::MAX;
857 let serialized = crate::json::to_string(&original).unwrap();
858 let deserialized: u8 = from_str(&serialized).unwrap();
859 assert_eq!(original, deserialized);
860 }
861
862 #[test]
863 fn test_i8_min() {
864 let original: i8 = i8::MIN;
865 let serialized = crate::json::to_string(&original).unwrap();
866 let deserialized: i8 = from_str(&serialized).unwrap();
867 assert_eq!(original, deserialized);
868 }
869
870 #[test]
871 fn test_i8_max() {
872 let original: i8 = i8::MAX;
873 let serialized = crate::json::to_string(&original).unwrap();
874 let deserialized: i8 = from_str(&serialized).unwrap();
875 assert_eq!(original, deserialized);
876 }
877
878 #[test]
879 fn test_i64_min() {
880 let original: i64 = i64::MIN;
881 let serialized = crate::json::to_string(&original).unwrap();
882 let deserialized: i64 = from_str(&serialized).unwrap();
883 assert_eq!(original, deserialized);
884 }
885
886 #[test]
887 fn test_i64_max() {
888 let original: i64 = i64::MAX;
889 let serialized = crate::json::to_string(&original).unwrap();
890 let deserialized: i64 = from_str(&serialized).unwrap();
891 assert_eq!(original, deserialized);
892 }
893
894 #[test]
895 fn test_string_owned() {
896 let original = String::from("Hello, World!");
897 let serialized = crate::json::to_string(&original).unwrap();
898 let deserialized: String = from_str(&serialized).unwrap();
899 assert_eq!(original, deserialized);
900 }
901
902 #[test]
903 fn test_string_borrowed() {
904 let original: &str = "Hello, World!";
905 let serialized = crate::json::to_string(&original).unwrap();
906 let deserialized: String = from_str(&serialized).unwrap();
907 assert_eq!(original, deserialized);
908 }
909
910 #[test]
911 fn test_vec_empty() {
912 let original: Vec<i32> = Vec::new();
913 let serialized = crate::json::to_string(&original).unwrap();
914 let deserialized: Vec<i32> = from_str(&serialized).unwrap();
915 assert_eq!(original, deserialized);
916 }
917
918 #[test]
919 fn test_vec_non_empty() {
920 let original = vec![1, 2, 3, 4, 5];
921 let serialized = crate::json::to_string(&original).unwrap();
922 let deserialized: Vec<i32> = from_str(&serialized).unwrap();
923 assert_eq!(original, deserialized);
924 }
925
926 #[test]
927 fn test_hashmap_empty() {
928 let original: HashMap<String, i32> = HashMap::new();
929 let serialized = crate::json::to_string(&original).unwrap();
930 let deserialized: HashMap<String, i32> = from_str(&serialized).unwrap();
931 assert_eq!(original, deserialized);
932 }
933
934 #[test]
935 fn test_hashmap_non_empty() {
936 let mut original = HashMap::new();
937 original.insert("key1".to_string(), 42);
938 original.insert("key2".to_string(), -10);
939 let serialized = crate::json::to_string(&original).unwrap();
940 let deserialized: HashMap<String, i32> = from_str(&serialized).unwrap();
941 assert_eq!(original, deserialized);
942 }
943
944 #[test]
945 fn test_option_some() {
946 let original: Option<i32> = Some(42);
947 let serialized = crate::json::to_string(&original).unwrap();
948 let deserialized: Option<i32> = from_str(&serialized).unwrap();
949 assert_eq!(original, deserialized);
950 }
951
952 #[test]
953 fn test_option_none() {
954 let original: Option<i32> = None;
955 let serialized = crate::json::to_string(&original).unwrap();
956 let deserialized: Option<i32> = from_str(&serialized).unwrap();
957 assert_eq!(original, deserialized);
958 }
959
960 #[test]
961 fn test_bool_true() {
962 let original = true;
963 let serialized = crate::json::to_string(&original).unwrap();
964 let deserialized: bool = from_str(&serialized).unwrap();
965 assert_eq!(original, deserialized);
966 }
967
968 #[test]
969 fn test_bool_false() {
970 let original = false;
971 let serialized = crate::json::to_string(&original).unwrap();
972 let deserialized: bool = from_str(&serialized).unwrap();
973 assert_eq!(original, deserialized);
974 }
975}
976
977mod doctest_playground {
979
980 #[allow(unused_imports)]
981 use crate as merde;
982
983 }