rocket/trace/
level.rs

1use std::fmt;
2
3use serde::{de, Serialize, Deserializer, Serializer};
4use tracing::{level_filters::LevelFilter, Level};
5
6pub fn serialize<S: Serializer>(level: &Option<Level>, s: S) -> Result<S::Ok, S::Error> {
7    LevelFilter::from(*level).to_string().serialize(s)
8}
9
10pub fn deserialize<'de, D: Deserializer<'de>>(de: D) -> Result<Option<Level>, D::Error> {
11    struct Visitor;
12
13    const E: &str = r#"one of "off", "error", "warn", "info", "debug", "trace", or 0-5"#;
14
15    impl<'de> de::Visitor<'de> for Visitor {
16        type Value = Option<Level>;
17
18        fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19            write!(f, "expected {E}")
20        }
21
22        fn visit_i64<E: de::Error>(self, v: i64) -> Result<Self::Value, E> {
23            v.try_into()
24                .map_err(|_| E::invalid_value(de::Unexpected::Signed(v), &E))
25                .and_then(|v| self.visit_u64(v))
26        }
27
28        fn visit_u64<E: de::Error>(self, v: u64) -> Result<Self::Value, E> {
29            let filter = match v {
30                0 => LevelFilter::OFF,
31                1 => LevelFilter::ERROR,
32                2 => LevelFilter::WARN,
33                3 => LevelFilter::INFO,
34                4 => LevelFilter::DEBUG,
35                5 => LevelFilter::TRACE,
36                _ => return Err(E::invalid_value(de::Unexpected::Unsigned(v), &E)),
37            };
38
39            Ok(filter.into_level())
40        }
41
42        fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
43            v.parse::<LevelFilter>()
44                .map(|f| f.into_level())
45                .map_err(|_| E::invalid_value(de::Unexpected::Str(v), &E))
46        }
47    }
48
49    de.deserialize_map(Visitor)
50}