squib_api/schemas/
logger.rs1use serde::{Deserialize, Serialize};
4
5use super::common::SafePath;
6
7#[derive(Debug, Clone, Copy, Eq, PartialEq, Default, Serialize, Deserialize)]
9pub enum LogLevel {
10 Off,
12 Error,
14 Warning,
16 #[default]
18 Info,
19 Debug,
21 Trace,
23}
24
25#[derive(Debug, Clone, Deserialize)]
27#[serde(deny_unknown_fields)]
28pub struct RawLoggerConfig {
29 pub log_path: String,
31 #[serde(default)]
33 pub level: LogLevel,
34 #[serde(default)]
36 pub show_level: bool,
37 #[serde(default)]
39 pub show_log_origin: bool,
40 #[serde(default)]
42 pub module: Option<String>,
43}
44
45#[derive(Debug, Clone, Serialize)]
47#[non_exhaustive]
48pub struct LoggerConfig {
49 pub log_path: SafePath,
51 pub level: LogLevel,
53 pub show_level: bool,
55 pub show_log_origin: bool,
57 pub module: Option<String>,
59}
60
61impl TryFrom<RawLoggerConfig> for LoggerConfig {
62 type Error = String;
63
64 fn try_from(raw: RawLoggerConfig) -> Result<Self, Self::Error> {
65 let log_path = SafePath::new(raw.log_path).map_err(|e| format!("Invalid log_path: {e}"))?;
66 if let Some(m) = raw.module.as_deref()
67 && (m.is_empty() || m.len() > 128)
68 {
69 return Err("Invalid module: must be 1..=128 bytes".into());
70 }
71 Ok(Self {
72 log_path,
73 level: raw.level,
74 show_level: raw.show_level,
75 show_log_origin: raw.show_log_origin,
76 module: raw.module,
77 })
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn test_should_accept_minimal_logger_config() {
87 let cfg = LoggerConfig::try_from(RawLoggerConfig {
88 log_path: "/tmp/squib.log".into(),
89 level: LogLevel::Info,
90 show_level: true,
91 show_log_origin: false,
92 module: None,
93 })
94 .unwrap();
95 assert_eq!(cfg.level, LogLevel::Info);
96 }
97
98 #[test]
99 fn test_should_default_level_to_info() {
100 let raw: RawLoggerConfig =
101 serde_json::from_str(r#"{"log_path":"/tmp/squib.log"}"#).unwrap();
102 assert_eq!(raw.level, LogLevel::Info);
103 }
104}