#[cfg(feature = "termcolor")]
use log::Level;
use log::LevelFilter;
use std::borrow::Cow;
#[cfg(feature = "termcolor")]
use termcolor::Color;
pub use time::{format_description::FormatItem, macros::format_description, UtcOffset};
#[derive(Debug, Clone, Copy)]
pub enum LevelPadding {
Left,
Right,
Off,
}
#[derive(Debug, Clone, Copy)]
pub enum ThreadPadding {
Left(usize),
Right(usize),
Off,
}
#[derive(Debug, Clone, Copy)]
pub enum TargetPadding {
Left(usize),
Right(usize),
Off,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ThreadLogMode {
IDs,
Names,
Both,
}
#[derive(Debug, Clone)]
pub(crate) enum TimeFormat {
Rfc2822,
Rfc3339,
Custom(&'static [time::format_description::FormatItem<'static>]),
}
#[derive(Debug, Clone)]
pub struct Config {
pub(crate) time: LevelFilter,
pub(crate) level: LevelFilter,
pub(crate) level_padding: LevelPadding,
pub(crate) thread: LevelFilter,
pub(crate) thread_log_mode: ThreadLogMode,
pub(crate) thread_padding: ThreadPadding,
pub(crate) target: LevelFilter,
pub(crate) target_padding: TargetPadding,
pub(crate) location: LevelFilter,
pub(crate) time_format: TimeFormat,
pub(crate) time_offset: UtcOffset,
pub(crate) filter_allow: Cow<'static, [Cow<'static, str>]>,
pub(crate) filter_ignore: Cow<'static, [Cow<'static, str>]>,
#[cfg(feature = "termcolor")]
pub(crate) level_color: [Option<Color>; 6],
pub(crate) write_log_enable_colors: bool,
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct ConfigBuilder(Config);
impl ConfigBuilder {
pub fn new() -> ConfigBuilder {
ConfigBuilder(Config::default())
}
pub fn set_max_level(&mut self, level: LevelFilter) -> &mut ConfigBuilder {
self.0.level = level;
self
}
pub fn set_time_level(&mut self, time: LevelFilter) -> &mut ConfigBuilder {
self.0.time = time;
self
}
pub fn set_thread_level(&mut self, thread: LevelFilter) -> &mut ConfigBuilder {
self.0.thread = thread;
self
}
pub fn set_target_level(&mut self, target: LevelFilter) -> &mut ConfigBuilder {
self.0.target = target;
self
}
pub fn set_target_padding(&mut self, padding: TargetPadding) -> &mut ConfigBuilder {
self.0.target_padding = padding;
self
}
pub fn set_location_level(&mut self, location: LevelFilter) -> &mut ConfigBuilder {
self.0.location = location;
self
}
pub fn set_level_padding(&mut self, padding: LevelPadding) -> &mut ConfigBuilder {
self.0.level_padding = padding;
self
}
pub fn set_thread_padding(&mut self, padding: ThreadPadding) -> &mut ConfigBuilder {
self.0.thread_padding = padding;
self
}
pub fn set_thread_mode(&mut self, mode: ThreadLogMode) -> &mut ConfigBuilder {
self.0.thread_log_mode = mode;
self
}
#[cfg(feature = "termcolor")]
pub fn set_level_color(&mut self, level: Level, color: Option<Color>) -> &mut ConfigBuilder {
self.0.level_color[level as usize] = color;
self
}
pub fn set_time_format_custom(
&mut self,
time_format: &'static [FormatItem<'static>],
) -> &mut ConfigBuilder {
self.0.time_format = TimeFormat::Custom(time_format);
self
}
pub fn set_time_format_rfc2822(&mut self) -> &mut ConfigBuilder {
self.0.time_format = TimeFormat::Rfc2822;
self
}
pub fn set_time_format_rfc3339(&mut self) -> &mut ConfigBuilder {
self.0.time_format = TimeFormat::Rfc3339;
self
}
pub fn set_time_offset(&mut self, offset: UtcOffset) -> &mut ConfigBuilder {
self.0.time_offset = offset;
self
}
#[cfg(feature = "local-offset")]
pub fn set_time_offset_to_local(&mut self) -> Result<&mut ConfigBuilder, &mut ConfigBuilder> {
match UtcOffset::current_local_offset() {
Ok(offset) => {
self.0.time_offset = offset;
Ok(self)
}
Err(_) => Err(self),
}
}
#[cfg(feature = "ansi_term")]
pub fn set_write_log_enable_colors(&mut self, local: bool) -> &mut ConfigBuilder {
self.0.write_log_enable_colors = local;
self
}
pub fn add_filter_allow_str(&mut self, filter_allow: &'static str) -> &mut ConfigBuilder {
let mut list = Vec::from(&*self.0.filter_allow);
list.push(Cow::Borrowed(filter_allow));
self.0.filter_allow = Cow::Owned(list);
self
}
pub fn add_filter_allow(&mut self, filter_allow: String) -> &mut ConfigBuilder {
let mut list = Vec::from(&*self.0.filter_allow);
list.push(Cow::Owned(filter_allow));
self.0.filter_allow = Cow::Owned(list);
self
}
pub fn clear_filter_allow(&mut self) -> &mut ConfigBuilder {
self.0.filter_allow = Cow::Borrowed(&[]);
self
}
pub fn add_filter_ignore_str(&mut self, filter_ignore: &'static str) -> &mut ConfigBuilder {
let mut list = Vec::from(&*self.0.filter_ignore);
list.push(Cow::Borrowed(filter_ignore));
self.0.filter_ignore = Cow::Owned(list);
self
}
pub fn add_filter_ignore(&mut self, filter_ignore: String) -> &mut ConfigBuilder {
let mut list = Vec::from(&*self.0.filter_ignore);
list.push(Cow::Owned(filter_ignore));
self.0.filter_ignore = Cow::Owned(list);
self
}
pub fn clear_filter_ignore(&mut self) -> &mut ConfigBuilder {
self.0.filter_ignore = Cow::Borrowed(&[]);
self
}
pub fn build(&mut self) -> Config {
self.0.clone()
}
}
impl Default for ConfigBuilder {
fn default() -> Self {
ConfigBuilder::new()
}
}
impl Default for Config {
fn default() -> Config {
Config {
time: LevelFilter::Error,
level: LevelFilter::Error,
level_padding: LevelPadding::Off,
thread: LevelFilter::Debug,
thread_log_mode: ThreadLogMode::IDs,
thread_padding: ThreadPadding::Off,
target: LevelFilter::Debug,
target_padding: TargetPadding::Off,
location: LevelFilter::Trace,
time_format: TimeFormat::Custom(format_description!("[hour]:[minute]:[second]")),
time_offset: UtcOffset::UTC,
filter_allow: Cow::Borrowed(&[]),
filter_ignore: Cow::Borrowed(&[]),
write_log_enable_colors: false,
#[cfg(feature = "termcolor")]
level_color: [
None, Some(Color::Red), Some(Color::Yellow), Some(Color::Blue), Some(Color::Cyan), Some(Color::White), ],
}
}
}