xref: /third_party/rust/crates/log/src/serde.rs (revision 2d8ae3ab)
1#![cfg(feature = "serde")]
2
3extern crate serde;
4use self::serde::de::{
5    Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error, Unexpected, VariantAccess,
6    Visitor,
7};
8use self::serde::ser::{Serialize, Serializer};
9
10use {Level, LevelFilter, LOG_LEVEL_NAMES};
11
12use std::fmt;
13use std::str::{self, FromStr};
14
15// The Deserialize impls are handwritten to be case insensitive using FromStr.
16
17impl Serialize for Level {
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
32impl<'de> Deserialize<'de> for Level {
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
111impl Serialize for LevelFilter {
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
127impl<'de> Deserialize<'de> for LevelFilter {
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)]
207mod 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
213    fn level_token(variant: &'static str) -> Token {
214        Token::UnitVariant {
215            name: "Level",
216            variant: variant,
217        }
218    }
219
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
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
236    fn level_filter_token(variant: &'static str) -> Token {
237        Token::UnitVariant {
238            name: "LevelFilter",
239            variant: variant,
240        }
241    }
242
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
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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