haxeformat/serde/
adapter.rs

1use std::fmt;
2use std::marker::PhantomData;
3use std::ops::{Deref, DerefMut};
4
5use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
6
7impl Serialize for crate::raw::HaxeDate {
8    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
9    where
10        S: Serializer,
11    {
12        serializer.serialize_i64(chrono::NaiveDateTime::from(*self).timestamp())
13    }
14}
15
16impl<'de> Deserialize<'de> for crate::raw::HaxeDate {
17    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
18    where
19        D: Deserializer<'de>,
20    {
21        let timestamp: i64 = Deserialize::deserialize(deserializer)?;
22        crate::raw::HaxeDate::try_from_timestamp(timestamp).ok_or_else(|| {
23            de::Error::invalid_value(de::Unexpected::Signed(timestamp), &"valid timestamp")
24        })
25    }
26}
27
28macro_rules! declare_markers {
29    ($vis:vis enum $marker_enum:ident($marker_prefix:expr) {
30        $(
31            $(#[$adapter_meta:meta])*
32            $marker_name:ident($adapter_vis:vis $adapter_name:ident($module:ident))
33        ),* $(,)?
34    }) => {
35        #[derive(Debug, Copy, Clone, Eq, PartialEq)]
36        $vis enum $marker_enum {
37            $($marker_name,)*
38            Unknown
39        }
40
41        impl $marker_enum {
42            $vis fn parse(string: &str) -> Option<Self> {
43                if !string.starts_with($marker_prefix) {
44                    return None;
45                }
46                match &string[$marker_prefix.len()..] {
47                    $(stringify!($marker_name) => Some(Self::$marker_name),)*
48                    _ => Some(Self::Unknown)
49                }
50            }
51
52            #[allow(clippy::wrong_self_convention)]
53            $vis fn to_str(&self) -> &'static str {
54                match *self {
55                    $(Self::$marker_name => concat!($marker_prefix, stringify!($marker_name)),)*
56                    Self::Unknown => concat!($marker_prefix, "unknown")
57                }
58            }
59        }
60
61        $(declare_markers!(
62            @declare_adapter $(#[$adapter_meta])*
63            $adapter_vis struct $adapter_name($module) => $marker_enum::$marker_name
64        );)*
65
66    };
67    (@declare_adapter $(#[$meta:meta])* $vis:vis struct $adapter:ident($module:ident) => $marker:path) => {
68
69        $(#[$meta])*
70        $vis mod $module {
71            #![allow(dead_code)]
72            use super::$adapter;
73            use serde::{ Serialize, Serializer, Deserialize, Deserializer };
74
75            pub fn serialize<T: Serialize, S: Serializer>(value: &T, ser: S) -> Result<S::Ok, S::Error> {
76                $adapter(value).serialize(ser)
77            }
78
79            pub fn deserialize<'de, T: Deserialize<'de>, D: Deserializer<'de>>(de: D) -> Result<T, D::Error> {
80                let val: $adapter<T> = Deserialize::deserialize(de)?;
81                Ok(val.0)
82            }
83        }
84
85        $(#[$meta])*
86        #[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
87        #[repr(transparent)]
88        $vis struct $adapter<T>($vis T);
89
90        impl<T: fmt::Display> fmt::Display for $adapter<T> {
91            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92                self.0.fmt(f)
93            }
94        }
95
96        impl<T> From<T> for $adapter<T> {
97            fn from(inner: T) -> Self { Self(inner) }
98        }
99
100        impl<T> Deref for $adapter<T> {
101            type Target = T;
102            fn deref(&self) -> &T { &self.0 }
103        }
104
105        impl<T> DerefMut for $adapter<T> {
106            fn deref_mut(&mut self) -> &mut T { &mut self.0 }
107        }
108
109        impl<T: Serialize> Serialize for $adapter<T> {
110            fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
111                ser.serialize_newtype_struct($marker.to_str(), &self.0)
112            }
113        }
114
115        impl<'de, T: Deserialize<'de>> Deserialize<'de> for $adapter<T> {
116            fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
117                let vis = AdapterVisitor {
118                    kind: $marker,
119                    _marker: PhantomData::<T>,
120                    _lifetime: PhantomData::<&'de ()>,
121                };
122                deserializer.deserialize_newtype_struct($marker.to_str(), vis)
123                    .map($adapter)
124            }
125        }
126    }
127}
128
129struct AdapterVisitor<'de, T> {
130    kind: AdapterMarker,
131    _marker: PhantomData<T>,
132    _lifetime: PhantomData<&'de ()>,
133}
134
135impl<'de, T: Deserialize<'de>> de::Visitor<'de> for AdapterVisitor<'de, T> {
136    type Value = T;
137    fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
138        write!(f, "adapter struct {:?}", self.kind)
139    }
140
141    fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<T, A::Error> {
142        match seq.next_element()? {
143            None => Err(<A::Error as de::Error>::invalid_length(0, &self)),
144            Some(value) => Ok(value),
145        }
146    }
147
148    fn visit_newtype_struct<D: Deserializer<'de>>(self, de: D) -> Result<T, D::Error> {
149        T::deserialize(de)
150    }
151}
152
153declare_markers! { pub(super) enum AdapterMarker("\0haxeformat::") {
154    /// Forces Haxe `Date` representation.
155    /// Accepts integers (as timestamps).
156    Date(pub DateAdapter(date)),
157    /// Forces Haxe `Array` representation (the default for sequences).
158    /// Accepts sequences, tuples and tuple structs.
159    Array(pub ArrayAdapter(array)),
160    /// Forces Haxe `List` representation.
161    /// Accepts sequences, tuples and tuple structs.
162    List(pub ListAdapter(list)),
163    /// Forces Haxe `struct` representation (the default for maps).
164    /// Accepts only structs and maps, with string keys.
165    Struct(pub StructAdapter(struct_obj)),
166    /// Forces Haxe `StringMap` representation.
167    /// Accepts only maps, with string keys.
168    StringMap(pub StringMapAdapter(string)),
169    /// Forces Haxe `IntMap` representation.
170    /// Accepts only maps, with integer keys.
171    IntMap(pub IntMapAdapter(int)),
172    /// Forces Haxe `ObjectMap` representation.
173    /// Accepts only maps, with arbitrary keys.
174    ObjectMap(pub ObjectMapAdapter(object)),
175    /// Forces Haxe `class` representation.
176    /// Accepts only structs.
177    Class(pub ClassAdapter(class)),
178    /// Forces Haxe `Class<T>` representation.
179    /// Accepts only strings.
180    ClassDef(pub ClassDefAdapter(class_def)),
181    /// Forces Haxe `Enum<T>` representation.
182    /// Accepts only strings.
183    EnumDef(pub EnumDefAdapter(enum_def)),
184    // TODO: add serde support for CustomAdapter
185    Custom(CustomAdapter(custom)),
186    /// Forces Haxe `exception` representation (throws on deserialization).
187    /// Accepts any value.
188    Exception(pub ExceptionAdapter(exception)),
189}}