bee_common/logger/
config.rs1use crate::logger::LOGGER_STDOUT_NAME;
5
6use log::LevelFilter;
7use serde::Deserialize;
8
9use std::borrow::Cow;
10
11const DEFAULT_TARGET_WIDTH: usize = 42;
13const DEFAULT_LEVEL_WIDTH: usize = 5;
15const DEFAULT_OUTPUT_NAME: &str = LOGGER_STDOUT_NAME;
17const DEFAULT_OUTPUT_LEVEL_FILTER: LevelFilter = LevelFilter::Info;
19const DEFAULT_COLOR_ENABLED: bool = true;
21
22#[derive(Default, Deserialize)]
24pub struct LoggerOutputConfigBuilder {
25 name: Option<String>,
27 level_filter: Option<LevelFilter>,
29 target_filters: Option<Vec<String>>,
31 target_exclusions: Option<Vec<String>>,
33 color_enabled: Option<bool>,
35}
36
37impl LoggerOutputConfigBuilder {
38 pub fn new() -> Self {
40 Self::default()
41 }
42
43 pub fn name<'a>(mut self, name: impl Into<Cow<'a, str>>) -> Self {
45 self.name.replace(name.into().into_owned());
46 self
47 }
48
49 pub fn level_filter(mut self, level: LevelFilter) -> Self {
51 self.level_filter.replace(level);
52 self
53 }
54
55 pub fn target_filters(mut self, target_filters: &[&str]) -> Self {
58 self.target_filters = Some(target_filters.iter().map(|f| f.to_string()).collect::<Vec<String>>());
59 self
60 }
61
62 pub fn color_enabled(mut self, color: bool) -> Self {
64 self.color_enabled.replace(color);
65 self
66 }
67
68 pub fn finish(self) -> LoggerOutputConfig {
70 LoggerOutputConfig {
71 name: self.name.unwrap_or_else(|| DEFAULT_OUTPUT_NAME.to_owned()),
72 level_filter: self.level_filter.unwrap_or(DEFAULT_OUTPUT_LEVEL_FILTER),
73 target_filters: self
74 .target_filters
75 .unwrap_or_else(Vec::new)
76 .iter()
77 .map(|f| f.to_lowercase())
78 .collect(),
79 target_exclusions: self
80 .target_exclusions
81 .unwrap_or_else(Vec::new)
82 .iter()
83 .map(|f| f.to_lowercase())
84 .collect(),
85 color_enabled: self.color_enabled.unwrap_or(DEFAULT_COLOR_ENABLED),
86 }
87 }
88}
89
90#[derive(Clone)]
92pub struct LoggerOutputConfig {
93 pub(crate) name: String,
95 pub(crate) level_filter: LevelFilter,
97 pub(crate) target_filters: Vec<String>,
99 pub(crate) target_exclusions: Vec<String>,
101 pub(crate) color_enabled: bool,
103}
104
105#[derive(Default, Deserialize)]
107pub struct LoggerConfigBuilder {
108 target_width: Option<usize>,
110 level_width: Option<usize>,
112 outputs: Option<Vec<LoggerOutputConfigBuilder>>,
114}
115
116impl LoggerConfigBuilder {
117 pub fn with_target_width(mut self, width: usize) -> Self {
119 self.target_width.replace(width);
120 self
121 }
122
123 pub fn with_level_width(mut self, width: usize) -> Self {
125 self.level_width.replace(width);
126 self
127 }
128
129 pub fn with_output(mut self, output: LoggerOutputConfigBuilder) -> Self {
131 self.outputs.get_or_insert_with(Vec::new).push(output);
132 self
133 }
134
135 pub fn level<'a>(&mut self, name: impl Into<Cow<'a, str>>, level: LevelFilter) {
137 let name = name.into();
138
139 if let Some(outputs) = self.outputs.as_deref_mut() {
140 if let Some(stdout) = outputs.iter_mut().find(|output| match output.name.as_ref() {
141 Some(output_name) => output_name[..] == name,
142 None => false,
143 }) {
144 stdout.level_filter.replace(level);
145 }
146 }
147 }
148
149 pub fn finish(self) -> LoggerConfig {
151 let outputs = self
152 .outputs
153 .map(|os| os.into_iter().map(|o| o.finish()).collect())
154 .unwrap_or_default();
155
156 LoggerConfig {
157 target_width: self.target_width.unwrap_or(DEFAULT_TARGET_WIDTH),
158 level_width: self.level_width.unwrap_or(DEFAULT_LEVEL_WIDTH),
159 outputs,
160 }
161 }
162}
163
164#[derive(Clone)]
166pub struct LoggerConfig {
167 pub(crate) target_width: usize,
169 pub(crate) level_width: usize,
171 pub(crate) outputs: Vec<LoggerOutputConfig>,
173}
174
175impl LoggerConfig {
176 pub fn build() -> LoggerConfigBuilder {
178 LoggerConfigBuilder::default()
179 }
180
181 pub fn target_width(&self) -> usize {
183 self.target_width
184 }
185
186 pub fn level_width(&self) -> usize {
188 self.level_width
189 }
190
191 pub fn outputs(&self) -> &[LoggerOutputConfig] {
193 &self.outputs
194 }
195}