1use std::path::PathBuf;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7pub struct LoggingConfig {
8 destinations: Vec<LogDestinationConfig>,
11}
12
13impl LoggingConfig {
14 pub fn new(destinations: Vec<LogDestinationConfig>) -> Self {
18 Self { destinations }
19 }
20
21 pub fn disabled() -> Self {
23 Self {
24 destinations: vec![],
25 }
26 }
27
28 pub fn destinations(&self) -> &[LogDestinationConfig] {
30 &self.destinations
31 }
32}
33
34#[derive(Debug, Clone, PartialEq, Eq)]
36#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
37pub struct LogDestinationConfig {
38 pub destination: LogDestination,
40
41 pub level: Option<log::LevelFilter>,
45}
46
47#[derive(Debug, Clone, PartialEq, Eq)]
49#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
50pub enum LogDestination {
51 Stderr,
53
54 File(PathBuf),
56
57 Syslog,
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn disabled() {
67 let config = LoggingConfig::disabled();
68 assert!(config.destinations().is_empty());
69 }
70
71 #[test]
72 fn new() {
73 let config = LoggingConfig::new(vec![
74 LogDestinationConfig {
75 destination: LogDestination::Stderr,
76 level: Some(log::LevelFilter::Info),
77 },
78 LogDestinationConfig {
79 destination: LogDestination::File(PathBuf::from("/tmp/logfile")),
80 level: Some(log::LevelFilter::Debug),
81 },
82 ]);
83 assert_eq!(
84 vec![
85 LogDestinationConfig {
86 destination: LogDestination::Stderr,
87 level: Some(log::LevelFilter::Info),
88 },
89 LogDestinationConfig {
90 destination: LogDestination::File(PathBuf::from("/tmp/logfile")),
91 level: Some(log::LevelFilter::Debug),
92 },
93 ],
94 config.destinations()
95 );
96 }
97
98 #[cfg(feature = "serde")]
99 #[test]
100 fn logging_config_round_trips_through_postcard() {
101 let cfg = LoggingConfig::new(vec![
102 LogDestinationConfig {
103 destination: LogDestination::Syslog,
104 level: Some(log::LevelFilter::Info),
105 },
106 LogDestinationConfig {
107 destination: LogDestination::File(PathBuf::from("/tmp/x.log")),
108 level: None,
109 },
110 LogDestinationConfig {
111 destination: LogDestination::Stderr,
112 level: Some(log::LevelFilter::Warn),
113 },
114 ]);
115 let bytes = postcard::to_stdvec(&cfg).unwrap();
116 let restored: LoggingConfig = postcard::from_bytes(&bytes).unwrap();
117 assert_eq!(cfg, restored);
118 }
119}