mm1_logger/
config.rs

1use std::fmt;
2
3pub use tracing::Level;
4
5#[derive(Debug, Clone, structopt::StructOpt, serde::Serialize, serde::Deserialize)]
6pub struct LoggingConfig {
7    #[structopt(long, default_value = "info")]
8    #[serde(with = "impl_serde_for_level")]
9    pub min_log_level: tracing::Level,
10
11    #[structopt(long)]
12    #[serde(default)]
13    pub log_target_filter: Vec<LogTargetConfig>,
14}
15
16// TODO: make it actually work, maybe?
17#[derive(Debug, Clone)]
18pub struct LogTargetConfig {
19    pub path:  Vec<String>,
20    pub level: tracing::Level,
21}
22
23impl std::str::FromStr for LogTargetConfig {
24    type Err = String;
25
26    fn from_str(s: &str) -> Result<Self, Self::Err> {
27        let (path, level) = s
28            .split_once('=')
29            .ok_or_else(|| "eq-sign missing".to_owned())?;
30        let level = level.parse::<tracing::Level>().map_err(|e| e.to_string())?;
31        let path = path.split("::").map(|s| s.to_owned()).collect();
32
33        let out = Self { path, level };
34        Ok(out)
35    }
36}
37
38impl fmt::Display for LogTargetConfig {
39    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40        format!("{}={}", self.path.join("*"), self.level).fmt(f)
41    }
42}
43
44mod impl_serde_for_log_target_config {
45    use super::*;
46    impl<'de> serde::Deserialize<'de> for LogTargetConfig {
47        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
48        where
49            D: serde::Deserializer<'de>,
50        {
51            use serde::de::Error as DeError;
52            String::deserialize(deserializer)?
53                .parse()
54                .map_err(D::Error::custom)
55        }
56    }
57
58    impl serde::Serialize for LogTargetConfig {
59        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
60        where
61            S: serde::Serializer,
62        {
63            self.to_string().serialize(serializer)
64        }
65    }
66}
67
68mod impl_serde_for_level {
69    use serde::de::Error as DeError;
70    use serde::{Deserialize, Deserializer, Serialize, Serializer};
71
72    pub(super) fn serialize<S>(value: &tracing::Level, ser: S) -> Result<S::Ok, S::Error>
73    where
74        S: Serializer,
75    {
76        value.to_string().serialize(ser)
77    }
78
79    pub(super) fn deserialize<'de, D>(deser: D) -> Result<tracing::Level, D::Error>
80    where
81        D: Deserializer<'de>,
82    {
83        String::deserialize(deser)?
84            .parse::<tracing::Level>()
85            .map_err(D::Error::custom)
86    }
87}