1use std::borrow::Cow;
2use std::collections::HashMap;
3use std::fmt::{self, Formatter};
4use std::mem;
5use std::ops::Deref;
6
7use serde::de::{
8 Deserialize,
9 DeserializeSeed,
10 Deserializer,
11 Error as SerdeError,
12 IntoDeserializer,
13 MapAccess,
14 Visitor
15};
16
17use types::{DateTime, JsonValue};
18
19macro_rules! string_enums {
20 (
21 $(
22 $(#[$attr:meta])*
23 pub enum $E:ident<$lifetime:tt> {
24 $(
25 $(#[$v_attr:meta])*
26 $V:ident($by:expr)
27 ),*;
28 $(#[$u_attr:meta])*
29 $U:ident(_),
30 }
31 )*
32 ) => {
33 $(
34 $(#[$attr])*
35 pub enum $E<$lifetime> {
36 $(
37 $(#[$v_attr])*
38 $V,
39 )*
40 $(#[$u_attr])*
41 $U(::std::borrow::Cow<$lifetime, str>),
42 }
43
44 impl<'de: 'a, 'a> ::serde::Deserialize<'de> for $E<'a> {
45 fn deserialize<D: ::serde::Deserializer<'de>>(d: D)
46 -> ::std::result::Result<Self, D::Error>
47 {
48 struct V;
49
50 impl<'a> ::serde::de::Visitor<'a> for V {
51 type Value = $E<'a>;
52
53 fn visit_str<E>(self, s: &str)
54 -> ::std::result::Result<$E<'a>, E>
55 {
56 match s {
57 $($by => Ok($E::$V),)*
58 _ => Ok($E::$U(s.to_owned().into())),
59 }
60 }
61
62 fn visit_borrowed_str<E>(self, s: &'a str)
63 -> ::std::result::Result<$E<'a>, E>
64 {
65 match s {
66 $($by => Ok($E::$V),)*
67 _ => Ok($E::$U(s.into())),
68 }
69 }
70
71 fn visit_string<E>(self, s: String)
72 -> ::std::result::Result<$E<'a>, E>
73 {
74 match s.as_str() {
75 $($by => Ok($E::$V),)*
76 _ => Ok($E::$U(s.into())),
77 }
78 }
79
80 fn expecting(&self, f: &mut ::std::fmt::Formatter)
81 -> ::std::fmt::Result
82 {
83 write!(f, "a string")
84 }
85 }
86
87 d.deserialize_str(V)
88 }
89 }
90
91 impl<'a> ::std::convert::AsRef<str> for $E<'a> {
92 fn as_ref(&self) -> &str {
93 match *self {
94 $($E::$V => $by,)*
95 $E::$U(ref s) => s,
96 }
97 }
98 }
99
100 impl<'a> ::std::cmp::PartialEq for $E<'a> {
101 fn eq(&self, other: &$E) -> bool {
102 match *self {
103 $($E::$V => match *other {
104 $E::$V => true,
105 $E::$U(ref s) if $by == s => true,
106 _ => false,
107 },)*
108 $E::$U(ref s) => match *other {
109 $($E::$V => $by == s,)*
110 $E::$U(ref t) => s == t,
111 },
112 }
113 }
114 }
115
116 impl<'a> ::std::hash::Hash for $E<'a> {
117 fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
118 match *self {
119 $($E::$V => $by.hash(state),)*
120 $E::$U(ref s) => s.hash(state),
121 }
122 }
123 }
124
125 impl<'a> ::std::cmp::Eq for $E<'a> {}
126 )*
127 }
128}
129
130#[derive(Deserialize, Eq, PartialEq, Hash)]
131pub struct CowStr<'a>(
132 #[serde(borrow)]
133 pub Cow<'a, str>
134);
135
136pub struct MapAccessChain<I, J, A> {
139 keys: I,
140 vals: J,
141 tail: A,
142}
143
144impl<'a> AsRef<str> for CowStr<'a> {
145 fn as_ref(&self) -> &str {
146 self.0.as_ref()
147 }
148}
149
150impl<'a> Deref for CowStr<'a> {
151 type Target = str;
152
153 fn deref(&self) -> &str {
154 self.as_ref()
155 }
156}
157
158impl<I: Iterator, J: Iterator, A> MapAccessChain<I, J, A> {
159 pub fn new<K, V>(keys: K, vals: V, a: A) -> MapAccessChain<I, J, A>
160 where
161 K: IntoIterator<IntoIter=I, Item=I::Item>,
162 V: IntoIterator<IntoIter=J, Item=J::Item>,
163 {
164 MapAccessChain {
165 keys: keys.into_iter(),
166 vals: vals.into_iter(),
167 tail: a,
168 }
169 }
170}
171
172impl<'de: 'a, 'a, I, J, A> MapAccess<'de> for MapAccessChain<I, J, A>
173where
174 I: Iterator<Item=Cow<'a, str>>,
175 J: Iterator<Item=JsonValue>,
176 A: MapAccess<'de>,
177{
178 type Error = A::Error;
179
180 fn next_key_seed<K: DeserializeSeed<'de>>(&mut self, seed: K)
181 -> Result<Option<K::Value>, A::Error>
182 {
183 if let Some(k) = self.keys.next() {
184 seed.deserialize(k.into_deserializer()).map(Some)
185 } else {
186 self.tail.next_key_seed(seed)
187 }
188 }
189
190 fn next_value_seed<V: DeserializeSeed<'de>>(&mut self, seed: V)
191 -> Result<V::Value, A::Error>
192 {
193 if let Some(v) = self.vals.next() {
194 seed.deserialize(v).map_err(A::Error::custom)
195 } else {
196 self.tail.next_value_seed(seed)
211 }
212 }
213}
214
215pub fn deserialize_default<'de, D, T>(d: D) -> Result<T, D::Error>
216 where D: Deserializer<'de>, T: Default + Deserialize<'de>
217{
218 Option::deserialize(d).map(|o| o.unwrap_or_else(T::default))
219}
220
221pub fn parse_datetime(s: &str) -> ::chrono::format::ParseResult<DateTime> {
222 use chrono::Utc;
223 use chrono::format::{self, Fixed, Item, Numeric, Pad, Parsed};
224
225 const ITEMS: &[Item] = &[
227 Item::Fixed(Fixed::ShortWeekdayName),
228 Item::Space(" "),
229 Item::Fixed(Fixed::ShortMonthName),
230 Item::Space(" "),
231 Item::Numeric(Numeric::Day, Pad::Space),
232 Item::Space(" "),
233 Item::Numeric(Numeric::Hour, Pad::Zero),
234 Item::Literal(":"),
235 Item::Numeric(Numeric::Minute, Pad::Zero),
236 Item::Literal(":"),
237 Item::Numeric(Numeric::Second, Pad::Zero),
238 Item::Space(" "),
239 Item::Fixed(Fixed::TimezoneOffset),
240 Item::Space(" "),
241 Item::Numeric(Numeric::Year, Pad::Zero),
242 ];
243
244 let mut parsed = Parsed::new();
245 format::parse(&mut parsed, s, ITEMS.iter().cloned())?;
246 parsed.to_datetime_with_timezone(&Utc)
247}
248
249pub fn deserialize_datetime<'x, D: Deserializer<'x>>(d: D) -> Result<DateTime, D::Error> {
250 struct DTVisitor;
251
252 impl<'x> Visitor<'x> for DTVisitor {
253 type Value = DateTime;
254
255 fn visit_str<E: SerdeError>(self, s: &str) -> Result<DateTime, E> {
256 parse_datetime(s).map_err(|e| E::custom(e.to_string()))
257 }
258
259 fn expecting(&self, f: &mut Formatter) -> fmt::Result {
260 write!(f, "a formatted date and time string")
261 }
262 }
263
264 d.deserialize_str(DTVisitor)
265}
266
267pub fn deserialize_map_cow_str<'de: 'a, 'a, D: Deserializer<'de>>(d: D)
269 -> Result<HashMap<Cow<'a, str>, Cow<'a, str>>, D::Error>
270{
271 #[derive(Deserialize)]
272 struct MapDeserialize<'a>(
273 #[serde(borrow)]
274 HashMap<CowStr<'a>, CowStr<'a>>
275 );
276
277 MapDeserialize::deserialize(d).map(|m| unsafe {
278 mem::transmute::<
279 HashMap<CowStr<'a>, CowStr<'a>>,
280 HashMap<Cow<'a, str>, Cow<'a, str>,
281 >>(m.0)
282 }).map_err(D::Error::custom)
283}
284
285pub fn deserialize_opt_cow_str<'de: 'a, 'a, D: Deserializer<'de>>(d: D)
287 -> Result<Option<Cow<'a, str>>, D::Error>
288{
289 #[derive(Deserialize)]
290 struct OptDeserialize<'a>(
291 #[serde(borrow)]
292 Option<CowStr<'a>>
293 );
294
295 OptDeserialize::deserialize(d)
296 .map(|de| de.0.map(|c| c.0))
297 .map_err(D::Error::custom)
298}
299
300pub fn deserialize_vec_cow_str<'de: 'a, 'a, D: Deserializer<'de>>(d: D)
302 -> Result<Vec<Cow<'a, str>>, D::Error>
303{
304 #[derive(Deserialize)]
305 struct VecDeserialize<'a>(
306 #[serde(borrow)]
307 Vec<CowStr<'a>>
308 );
309
310 VecDeserialize::deserialize(d).map(|v| unsafe {
311 mem::transmute::<Vec<CowStr<'a>>, Vec<Cow<'a, str>>>(v.0)
312 }).map_err(D::Error::custom)
313}
314
315#[cfg(test)]
316mod tests {
317 use json;
318
319 use super::*;
320
321 #[test]
322 fn test_deserialize_default() {
323 use json;
324
325 #[derive(Debug, Default, Deserialize, PartialEq)]
326 struct S {
327 #[serde(deserialize_with = "deserialize_default")]
328 #[serde(default)]
329 n: u32,
330 #[serde(deserialize_with = "deserialize_default")]
331 #[serde(default)]
332 o: Option<bool>,
333 #[serde(deserialize_with = "deserialize_default")]
334 #[serde(default)]
335 s: String,
336 #[serde(deserialize_with = "deserialize_default")]
337 #[serde(default)]
338 v: Vec<u8>,
339 }
340
341 assert_eq!(
342 json::from_str::<S>(r#"{"n":null,"s":null}"#).unwrap(),
343 json::from_str(r#"{"o":null,"v":null}"#).unwrap()
344 );
345 assert_eq!(
346 S { n: 1, o: Some(true), s: "s".to_owned(), v: vec![255] },
347 json::from_str(r#"{"n":1,"o":true,"s":"s","v":[255]}"#).unwrap()
348 );
349 }
350
351 #[test]
352 fn test_parse_datetime() {
353 use chrono::{NaiveDate, Utc};
354 use types::DateTime;
355
356 assert_eq!(
357 DateTime::from_utc(NaiveDate::from_ymd(2017, 5, 1).and_hms(0, 1, 2), Utc),
358 parse_datetime("Mon May 01 00:01:02 +0000 2017").unwrap()
359 );
360 assert!(parse_datetime("2017-05-01T00:01:02Z").is_err());
361 }
362
363 #[test]
364 fn test_deserialize_cow() {
365 match deserialize_map_cow_str(
366 &mut json::Deserializer::from_str(r#"{"a":"b"}"#)
367 ).unwrap().into_iter().next().unwrap()
368 {
369 (Cow::Borrowed(_), Cow::Borrowed(_)) => (),
370 _ => panic!("`deserialize_map_cow_str` didn't borrow")
371 }
372
373 if let Cow::Owned(_) = deserialize_opt_cow_str(
374 &mut json::Deserializer::from_str(r#""a""#)
375 ).unwrap().unwrap()
376 {
377 panic!("`deserialize_opt_cow_str` didn't borrow");
378 }
379
380 if let Cow::Owned(_) = deserialize_vec_cow_str(
381 &mut json::Deserializer::from_str(r#"["a"]"#)
382 ).unwrap()[0]
383 {
384 panic!("`deserialize_vec_cow_str` didn't borrow");
385 }
386 }
387}