• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![cfg(feature = "serde")]
2 
3 extern crate serde;
4 use self::serde::de::{
5     Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error, Unexpected, VariantAccess,
6     Visitor,
7 };
8 use self::serde::ser::{Serialize, Serializer};
9 
10 use {Level, LevelFilter, LOG_LEVEL_NAMES};
11 
12 use std::fmt;
13 use std::str::{self, FromStr};
14 
15 // The Deserialize impls are handwritten to be case insensitive using FromStr.
16 
17 impl Serialize for Level {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,18     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
19     where
20         S: Serializer,
21     {
22         match *self {
23             Level::Error => serializer.serialize_unit_variant("Level", 0, "ERROR"),
24             Level::Warn => serializer.serialize_unit_variant("Level", 1, "WARN"),
25             Level::Info => serializer.serialize_unit_variant("Level", 2, "INFO"),
26             Level::Debug => serializer.serialize_unit_variant("Level", 3, "DEBUG"),
27             Level::Trace => serializer.serialize_unit_variant("Level", 4, "TRACE"),
28         }
29     }
30 }
31 
32 impl<'de> Deserialize<'de> for Level {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,33     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
34     where
35         D: Deserializer<'de>,
36     {
37         struct LevelIdentifier;
38 
39         impl<'de> Visitor<'de> for LevelIdentifier {
40             type Value = Level;
41 
42             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
43                 formatter.write_str("log level")
44             }
45 
46             fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
47             where
48                 E: Error,
49             {
50                 // Case insensitive.
51                 FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES[1..]))
52             }
53 
54             fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
55             where
56                 E: Error,
57             {
58                 let variant = str::from_utf8(value)
59                     .map_err(|_| Error::invalid_value(Unexpected::Bytes(value), &self))?;
60 
61                 self.visit_str(variant)
62             }
63 
64             fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
65             where
66                 E: Error,
67             {
68                 let variant = LOG_LEVEL_NAMES[1..]
69                     .get(v as usize)
70                     .ok_or_else(|| Error::invalid_value(Unexpected::Unsigned(v), &self))?;
71 
72                 self.visit_str(variant)
73             }
74         }
75 
76         impl<'de> DeserializeSeed<'de> for LevelIdentifier {
77             type Value = Level;
78 
79             fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
80             where
81                 D: Deserializer<'de>,
82             {
83                 deserializer.deserialize_identifier(LevelIdentifier)
84             }
85         }
86 
87         struct LevelEnum;
88 
89         impl<'de> Visitor<'de> for LevelEnum {
90             type Value = Level;
91 
92             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
93                 formatter.write_str("log level")
94             }
95 
96             fn visit_enum<A>(self, value: A) -> Result<Self::Value, A::Error>
97             where
98                 A: EnumAccess<'de>,
99             {
100                 let (level, variant) = value.variant_seed(LevelIdentifier)?;
101                 // Every variant is a unit variant.
102                 variant.unit_variant()?;
103                 Ok(level)
104             }
105         }
106 
107         deserializer.deserialize_enum("Level", &LOG_LEVEL_NAMES[1..], LevelEnum)
108     }
109 }
110 
111 impl Serialize for LevelFilter {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,112     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
113     where
114         S: Serializer,
115     {
116         match *self {
117             LevelFilter::Off => serializer.serialize_unit_variant("LevelFilter", 0, "OFF"),
118             LevelFilter::Error => serializer.serialize_unit_variant("LevelFilter", 1, "ERROR"),
119             LevelFilter::Warn => serializer.serialize_unit_variant("LevelFilter", 2, "WARN"),
120             LevelFilter::Info => serializer.serialize_unit_variant("LevelFilter", 3, "INFO"),
121             LevelFilter::Debug => serializer.serialize_unit_variant("LevelFilter", 4, "DEBUG"),
122             LevelFilter::Trace => serializer.serialize_unit_variant("LevelFilter", 5, "TRACE"),
123         }
124     }
125 }
126 
127 impl<'de> Deserialize<'de> for LevelFilter {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,128     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
129     where
130         D: Deserializer<'de>,
131     {
132         struct LevelFilterIdentifier;
133 
134         impl<'de> Visitor<'de> for LevelFilterIdentifier {
135             type Value = LevelFilter;
136 
137             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
138                 formatter.write_str("log level filter")
139             }
140 
141             fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
142             where
143                 E: Error,
144             {
145                 // Case insensitive.
146                 FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES))
147             }
148 
149             fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
150             where
151                 E: Error,
152             {
153                 let variant = str::from_utf8(value)
154                     .map_err(|_| Error::invalid_value(Unexpected::Bytes(value), &self))?;
155 
156                 self.visit_str(variant)
157             }
158 
159             fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
160             where
161                 E: Error,
162             {
163                 let variant = LOG_LEVEL_NAMES
164                     .get(v as usize)
165                     .ok_or_else(|| Error::invalid_value(Unexpected::Unsigned(v), &self))?;
166 
167                 self.visit_str(variant)
168             }
169         }
170 
171         impl<'de> DeserializeSeed<'de> for LevelFilterIdentifier {
172             type Value = LevelFilter;
173 
174             fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
175             where
176                 D: Deserializer<'de>,
177             {
178                 deserializer.deserialize_identifier(LevelFilterIdentifier)
179             }
180         }
181 
182         struct LevelFilterEnum;
183 
184         impl<'de> Visitor<'de> for LevelFilterEnum {
185             type Value = LevelFilter;
186 
187             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
188                 formatter.write_str("log level filter")
189             }
190 
191             fn visit_enum<A>(self, value: A) -> Result<Self::Value, A::Error>
192             where
193                 A: EnumAccess<'de>,
194             {
195                 let (level_filter, variant) = value.variant_seed(LevelFilterIdentifier)?;
196                 // Every variant is a unit variant.
197                 variant.unit_variant()?;
198                 Ok(level_filter)
199             }
200         }
201 
202         deserializer.deserialize_enum("LevelFilter", &LOG_LEVEL_NAMES, LevelFilterEnum)
203     }
204 }
205 
206 #[cfg(test)]
207 mod tests {
208     extern crate serde_test;
209     use self::serde_test::{assert_de_tokens, assert_de_tokens_error, assert_tokens, Token};
210 
211     use {Level, LevelFilter};
212 
level_token(variant: &'static str) -> Token213     fn level_token(variant: &'static str) -> Token {
214         Token::UnitVariant {
215             name: "Level",
216             variant: variant,
217         }
218     }
219 
level_bytes_tokens(variant: &'static [u8]) -> [Token; 3]220     fn level_bytes_tokens(variant: &'static [u8]) -> [Token; 3] {
221         [
222             Token::Enum { name: "Level" },
223             Token::Bytes(variant),
224             Token::Unit,
225         ]
226     }
227 
level_variant_tokens(variant: u32) -> [Token; 3]228     fn level_variant_tokens(variant: u32) -> [Token; 3] {
229         [
230             Token::Enum { name: "Level" },
231             Token::U32(variant),
232             Token::Unit,
233         ]
234     }
235 
level_filter_token(variant: &'static str) -> Token236     fn level_filter_token(variant: &'static str) -> Token {
237         Token::UnitVariant {
238             name: "LevelFilter",
239             variant: variant,
240         }
241     }
242 
level_filter_bytes_tokens(variant: &'static [u8]) -> [Token; 3]243     fn level_filter_bytes_tokens(variant: &'static [u8]) -> [Token; 3] {
244         [
245             Token::Enum {
246                 name: "LevelFilter",
247             },
248             Token::Bytes(variant),
249             Token::Unit,
250         ]
251     }
252 
level_filter_variant_tokens(variant: u32) -> [Token; 3]253     fn level_filter_variant_tokens(variant: u32) -> [Token; 3] {
254         [
255             Token::Enum {
256                 name: "LevelFilter",
257             },
258             Token::U32(variant),
259             Token::Unit,
260         ]
261     }
262 
263     #[test]
test_level_ser_de()264     fn test_level_ser_de() {
265         let cases = [
266             (Level::Error, [level_token("ERROR")]),
267             (Level::Warn, [level_token("WARN")]),
268             (Level::Info, [level_token("INFO")]),
269             (Level::Debug, [level_token("DEBUG")]),
270             (Level::Trace, [level_token("TRACE")]),
271         ];
272 
273         for &(s, expected) in &cases {
274             assert_tokens(&s, &expected);
275         }
276     }
277 
278     #[test]
test_level_case_insensitive()279     fn test_level_case_insensitive() {
280         let cases = [
281             (Level::Error, [level_token("error")]),
282             (Level::Warn, [level_token("warn")]),
283             (Level::Info, [level_token("info")]),
284             (Level::Debug, [level_token("debug")]),
285             (Level::Trace, [level_token("trace")]),
286         ];
287 
288         for &(s, expected) in &cases {
289             assert_de_tokens(&s, &expected);
290         }
291     }
292 
293     #[test]
test_level_de_bytes()294     fn test_level_de_bytes() {
295         let cases = [
296             (Level::Error, level_bytes_tokens(b"ERROR")),
297             (Level::Warn, level_bytes_tokens(b"WARN")),
298             (Level::Info, level_bytes_tokens(b"INFO")),
299             (Level::Debug, level_bytes_tokens(b"DEBUG")),
300             (Level::Trace, level_bytes_tokens(b"TRACE")),
301         ];
302 
303         for &(value, tokens) in &cases {
304             assert_de_tokens(&value, &tokens);
305         }
306     }
307 
308     #[test]
test_level_de_variant_index()309     fn test_level_de_variant_index() {
310         let cases = [
311             (Level::Error, level_variant_tokens(0)),
312             (Level::Warn, level_variant_tokens(1)),
313             (Level::Info, level_variant_tokens(2)),
314             (Level::Debug, level_variant_tokens(3)),
315             (Level::Trace, level_variant_tokens(4)),
316         ];
317 
318         for &(value, tokens) in &cases {
319             assert_de_tokens(&value, &tokens);
320         }
321     }
322 
323     #[test]
test_level_de_error()324     fn test_level_de_error() {
325         let msg = "unknown variant `errorx`, expected one of \
326                    `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`";
327         assert_de_tokens_error::<Level>(&[level_token("errorx")], msg);
328     }
329 
330     #[test]
test_level_filter_ser_de()331     fn test_level_filter_ser_de() {
332         let cases = [
333             (LevelFilter::Off, [level_filter_token("OFF")]),
334             (LevelFilter::Error, [level_filter_token("ERROR")]),
335             (LevelFilter::Warn, [level_filter_token("WARN")]),
336             (LevelFilter::Info, [level_filter_token("INFO")]),
337             (LevelFilter::Debug, [level_filter_token("DEBUG")]),
338             (LevelFilter::Trace, [level_filter_token("TRACE")]),
339         ];
340 
341         for &(s, expected) in &cases {
342             assert_tokens(&s, &expected);
343         }
344     }
345 
346     #[test]
test_level_filter_case_insensitive()347     fn test_level_filter_case_insensitive() {
348         let cases = [
349             (LevelFilter::Off, [level_filter_token("off")]),
350             (LevelFilter::Error, [level_filter_token("error")]),
351             (LevelFilter::Warn, [level_filter_token("warn")]),
352             (LevelFilter::Info, [level_filter_token("info")]),
353             (LevelFilter::Debug, [level_filter_token("debug")]),
354             (LevelFilter::Trace, [level_filter_token("trace")]),
355         ];
356 
357         for &(s, expected) in &cases {
358             assert_de_tokens(&s, &expected);
359         }
360     }
361 
362     #[test]
test_level_filter_de_bytes()363     fn test_level_filter_de_bytes() {
364         let cases = [
365             (LevelFilter::Off, level_filter_bytes_tokens(b"OFF")),
366             (LevelFilter::Error, level_filter_bytes_tokens(b"ERROR")),
367             (LevelFilter::Warn, level_filter_bytes_tokens(b"WARN")),
368             (LevelFilter::Info, level_filter_bytes_tokens(b"INFO")),
369             (LevelFilter::Debug, level_filter_bytes_tokens(b"DEBUG")),
370             (LevelFilter::Trace, level_filter_bytes_tokens(b"TRACE")),
371         ];
372 
373         for &(value, tokens) in &cases {
374             assert_de_tokens(&value, &tokens);
375         }
376     }
377 
378     #[test]
test_level_filter_de_variant_index()379     fn test_level_filter_de_variant_index() {
380         let cases = [
381             (LevelFilter::Off, level_filter_variant_tokens(0)),
382             (LevelFilter::Error, level_filter_variant_tokens(1)),
383             (LevelFilter::Warn, level_filter_variant_tokens(2)),
384             (LevelFilter::Info, level_filter_variant_tokens(3)),
385             (LevelFilter::Debug, level_filter_variant_tokens(4)),
386             (LevelFilter::Trace, level_filter_variant_tokens(5)),
387         ];
388 
389         for &(value, tokens) in &cases {
390             assert_de_tokens(&value, &tokens);
391         }
392     }
393 
394     #[test]
test_level_filter_de_error()395     fn test_level_filter_de_error() {
396         let msg = "unknown variant `errorx`, expected one of \
397                    `OFF`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`";
398         assert_de_tokens_error::<LevelFilter>(&[level_filter_token("errorx")], msg);
399     }
400 }
401