support_kit/
logs.rs

1mod log_file_config;
2mod log_level;
3mod log_level_config;
4mod log_rotation;
5mod log_target;
6mod logger_config;
7mod logger_preset;
8mod logging;
9
10pub use log_file_config::LogFileConfig;
11pub use log_level::LogLevel;
12pub use log_level_config::LogLevelConfig;
13pub use log_rotation::LogRotation;
14pub use log_target::LogTarget;
15pub use logger_config::LoggerConfig;
16pub use logger_preset::LoggerPreset;
17pub use logging::Logging;
18
19use crate::{ConfigOrPreset, OneOrMany};
20
21pub type LoggerConfigOrPreset = ConfigOrPreset<LoggerConfig, LoggerPreset>;
22pub type LoggingConfig = OneOrMany<LoggerConfigOrPreset>;
23
24impl LoggingConfig {
25    pub fn loggers(&self) -> Vec<LoggerConfig> {
26        match self {
27            Self::Many(config_or_preset) => config_or_preset
28                .into_iter()
29                .cloned()
30                .map(Into::into)
31                .collect(),
32            Self::One(config_or_preset) => vec![config_or_preset.clone().into()],
33        }
34    }
35}
36
37impl Default for LoggingConfig {
38    fn default() -> Self {
39        Self::Many(bon::vec![LoggerPreset::Stdout, LoggerPreset::Stderr,])
40    }
41}
42
43#[test]
44fn single_logger_notation() -> Result<(), Box<dyn std::error::Error>> {
45    use super::{LogLevel, LoggerConfig};
46
47    let config: LoggingConfig = serde_json::from_str(
48        r#"
49        {
50            "directory": "logs",
51            "level": "warn",
52            "name": "app.error"
53        }
54        "#,
55    )?;
56
57    assert_eq!(
58        config,
59        OneOrMany::One(
60            LoggerConfig::builder()
61                .level(LogLevel::Warn)
62                .file(("logs", "app.error"))
63                .build()
64                .into()
65        ),
66    );
67
68    Ok(())
69}
70
71#[test]
72fn multiple_loggers_notation() -> Result<(), Box<dyn std::error::Error>> {
73    use super::{LogLevel, LogRotation, LoggerConfig};
74
75    let config: LoggingConfig = serde_json::from_str(
76        r#"
77        [{
78            "directory": "logs",
79            "level": { "min": "info", "max": "warn" },
80            "name": "app",
81            "rotation": "daily"
82        }]
83        "#,
84    )?;
85
86    assert_eq!(
87        config,
88        vec![LoggerConfig::builder()
89            .level(LogLevel::Info..LogLevel::Warn)
90            .file(("logs", "app", LogRotation::Daily))
91            .build()
92            .into()]
93        .into(),
94    );
95
96    Ok(())
97}