1use std::fmt;
2
3use serde::{
4 de::{Error, MapAccess, SeqAccess, Visitor},
5 Deserialize, Deserializer, Serialize, Serializer,
6};
7
8use crate::variant::Variant;
9
10impl Serialize for Variant {
11 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
12 where
13 S: Serializer,
14 {
15 match self {
16 Variant::None => serializer.serialize_none(),
17 Variant::Bool(value) => serializer.serialize_bool(*value),
18 #[cfg(not(feature = "serde-prefix-nums"))]
19 Variant::Int8(value) => serializer.serialize_i8(*value),
20 #[cfg(feature = "serde-prefix-nums")]
21 Variant::Int8(value) => serializer.serialize_str(&format!("@i8:{}", *value)),
22 #[cfg(not(feature = "serde-prefix-nums"))]
23 Variant::UInt8(value) => serializer.serialize_u8(*value),
24 #[cfg(feature = "serde-prefix-nums")]
25 Variant::UInt8(value) => serializer.serialize_str(&format!("@u8:{}", *value)),
26 #[cfg(not(feature = "serde-prefix-nums"))]
27 Variant::Int16(value) => serializer.serialize_i16(*value),
28 #[cfg(feature = "serde-prefix-nums")]
29 Variant::Int16(value) => serializer.serialize_str(&format!("@i16:{}", *value)),
30 #[cfg(not(feature = "serde-prefix-nums"))]
31 Variant::UInt16(value) => serializer.serialize_u16(*value),
32 #[cfg(feature = "serde-prefix-nums")]
33 Variant::UInt16(value) => serializer.serialize_str(&format!("@u16:{}", *value)),
34 #[cfg(not(feature = "serde-prefix-nums"))]
35 Variant::Int32(value) => serializer.serialize_i32(*value),
36 #[cfg(feature = "serde-prefix-nums")]
37 Variant::Int32(value) => serializer.serialize_str(&format!("@i32:{}", *value)),
38 #[cfg(not(feature = "serde-prefix-nums"))]
39 Variant::UInt32(value) => serializer.serialize_u32(*value),
40 #[cfg(feature = "serde-prefix-nums")]
41 Variant::UInt32(value) => serializer.serialize_str(&format!("@u32:{}", *value)),
42 #[cfg(not(feature = "serde-prefix-nums"))]
43 Variant::Int64(value) => serializer.serialize_i64(*value),
44 #[cfg(feature = "serde-prefix-nums")]
45 Variant::Int64(value) => {
46 if *value < 0 {
47 serializer.serialize_i64(*value)
48 } else {
49 serializer.serialize_str(&format!("@i64:{}", *value))
50 }
51 }
52 Variant::UInt64(value) => serializer.serialize_u64(*value),
53 #[cfg(not(feature = "serde-prefix-nums"))]
54 Variant::Float(value) => serializer.serialize_f32(*value),
55 #[cfg(feature = "serde-prefix-nums")]
56 Variant::Float(value) => serializer.serialize_str(&format!("@f:{}", *value)),
57 Variant::Double(value) => serializer.serialize_f64(*value),
58 #[cfg(not(feature = "serde-prefix-nums"))]
59 Variant::String(value) => serializer.serialize_str(value),
60 #[cfg(feature = "serde-prefix-nums")]
61 Variant::String(value) => {
62 if value.starts_with("@") {
63 return serializer.serialize_str(&format!("@{}", value));
64 } else {
65 return serializer.serialize_str(value);
66 }
67 }
68 Variant::Buffer(value) => serializer.serialize_bytes(value),
69 Variant::Array(value) => value.serialize(serializer),
70 Variant::Dict(value) => value.serialize(serializer),
71 }
72 }
73}
74
75impl<'de> Deserialize<'de> for Variant {
76 fn deserialize<D>(deserializer: D) -> Result<Variant, D::Error>
77 where
78 D: Deserializer<'de>,
79 {
80 struct VariantVisitor;
81
82 impl<'de> Visitor<'de> for VariantVisitor {
83 type Value = Variant;
84
85 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> fmt::Result {
86 formatter.write_str("a valid Variant")
87 }
88
89 fn visit_none<E>(self) -> Result<Variant, E> {
90 Ok(Variant::None)
91 }
92
93 fn visit_bool<E>(self, value: bool) -> Result<Variant, E> {
94 Ok(Variant::Bool(value))
95 }
96
97 #[cfg(not(feature = "serde-prefix-nums"))]
98 fn visit_i8<E>(self, value: i8) -> Result<Variant, E> {
99 Ok(Variant::Int8(value))
100 }
101
102 #[cfg(not(feature = "serde-prefix-nums"))]
103 fn visit_u8<E>(self, value: u8) -> Result<Variant, E> {
104 Ok(Variant::UInt8(value))
105 }
106
107 #[cfg(not(feature = "serde-prefix-nums"))]
108 fn visit_i16<E>(self, value: i16) -> Result<Variant, E> {
109 Ok(Variant::Int16(value))
110 }
111
112 #[cfg(not(feature = "serde-prefix-nums"))]
113 fn visit_u16<E>(self, value: u16) -> Result<Variant, E> {
114 Ok(Variant::UInt16(value))
115 }
116
117 #[cfg(not(feature = "serde-prefix-nums"))]
118 fn visit_i32<E>(self, value: i32) -> Result<Variant, E> {
119 Ok(Variant::Int32(value))
120 }
121
122 #[cfg(not(feature = "serde-prefix-nums"))]
123 fn visit_u32<E>(self, value: u32) -> Result<Variant, E> {
124 Ok(Variant::UInt32(value))
125 }
126
127 fn visit_i64<E>(self, value: i64) -> Result<Variant, E> {
128 Ok(Variant::Int64(value))
129 }
130
131 fn visit_u64<E>(self, value: u64) -> Result<Variant, E> {
132 Ok(Variant::UInt64(value))
133 }
134
135 #[cfg(not(feature = "serde-prefix-nums"))]
136 fn visit_f32<E>(self, value: f32) -> Result<Variant, E> {
137 Ok(Variant::Float(value))
138 }
139
140 fn visit_f64<E>(self, value: f64) -> Result<Variant, E> {
141 Ok(Variant::Double(value))
142 }
143
144 fn visit_str<E>(self, value: &str) -> Result<Variant, E>
145 where
146 E: Error,
147 {
148 #[cfg(feature = "serde-prefix-nums")]
149 if value.starts_with("@") {
150 let str = &value[1..];
151
152 let result = match str {
153 s if s.starts_with("i8:") => s[3..].parse().map(Variant::Int8).map_err(Error::custom),
154 s if s.starts_with("u8:") => s[3..].parse().map(Variant::UInt8).map_err(Error::custom),
155 s if s.starts_with("i16:") => s[4..].parse().map(Variant::Int16).map_err(Error::custom),
156 s if s.starts_with("u16:") => s[4..].parse().map(Variant::UInt16).map_err(Error::custom),
157 s if s.starts_with("i32:") => s[4..].parse().map(Variant::Int32).map_err(Error::custom),
158 s if s.starts_with("u32:") => s[4..].parse().map(Variant::UInt32).map_err(Error::custom),
159 s if s.starts_with("i64:") => s[4..].parse().map(Variant::Int64).map_err(Error::custom),
160 s if s.starts_with("f:") => s[2..].parse().map(Variant::Float).map_err(Error::custom),
161 s if s.starts_with("@") => Ok(Variant::String(s.to_string())),
162 _s => Ok(Variant::String(value.to_string())),
163 };
164
165 return result;
166 };
167
168 Ok(Variant::String(value.to_string()))
169 }
170
171 fn visit_bytes<E>(self, v: &[u8]) -> Result<Variant, E> {
172 Ok(Variant::Buffer(v.to_vec()))
173 }
174
175 fn visit_seq<A>(self, mut seq: A) -> Result<Variant, A::Error>
176 where
177 A: SeqAccess<'de>,
178 {
179 let mut vec = Vec::new();
180 while let Some(value) = seq.next_element()? {
181 vec.push(value);
182 }
183 Ok(Variant::Array(vec))
184 }
185
186 fn visit_map<A>(self, mut map: A) -> Result<Variant, A::Error>
187 where
188 A: MapAccess<'de>,
189 {
190 let mut dict = Variant::new_dict();
191 while let Some((key, value)) = map.next_entry::<&str, Variant>()? {
192 dict.dict_set(key, value);
193 }
194 Ok(dict)
195 }
196 }
197
198 deserializer.deserialize_any(VariantVisitor)
199 }
200}