haxeformat/serde/
adapter.rs1use 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 Date(pub DateAdapter(date)),
157 Array(pub ArrayAdapter(array)),
160 List(pub ListAdapter(list)),
163 Struct(pub StructAdapter(struct_obj)),
166 StringMap(pub StringMapAdapter(string)),
169 IntMap(pub IntMapAdapter(int)),
172 ObjectMap(pub ObjectMapAdapter(object)),
175 Class(pub ClassAdapter(class)),
178 ClassDef(pub ClassDefAdapter(class_def)),
181 EnumDef(pub EnumDefAdapter(enum_def)),
184 Custom(CustomAdapter(custom)),
186 Exception(pub ExceptionAdapter(exception)),
189}}