use crate::Append;
use crate::Diagnostic;
use crate::Filter;
use crate::Logger;
use crate::logger::log_impl::Dispatch;
use crate::logger::log_impl::set_default_logger;
pub fn builder() -> LoggerBuilder {
LoggerBuilder { dispatches: vec![] }
}
#[must_use = "call `apply` to set the global logger or `build` to construct a logger instance"]
#[derive(Debug)]
pub struct LoggerBuilder {
dispatches: Vec<Dispatch>,
}
impl LoggerBuilder {
pub fn dispatch<F>(mut self, f: F) -> Self
where
F: FnOnce(DispatchBuilder<false>) -> DispatchBuilder<true>,
{
self.dispatches.push(f(DispatchBuilder::new()).build());
self
}
pub fn build(self) -> Logger {
Logger::new(self.dispatches)
}
pub fn try_apply(self) -> Result<(), Logger> {
set_default_logger(self.build())
}
pub fn apply(self) {
self.try_apply()
.expect("LoggerBuilder::apply must be called before the global logger initialized");
}
}
#[derive(Debug)]
pub struct DispatchBuilder<const APPEND: bool> {
filters: Vec<Box<dyn Filter>>,
diagnostics: Vec<Box<dyn Diagnostic>>,
appends: Vec<Box<dyn Append>>,
}
impl DispatchBuilder<false> {
fn new() -> Self {
DispatchBuilder {
filters: vec![],
diagnostics: vec![],
appends: vec![],
}
}
pub fn filter(mut self, filter: impl Into<Box<dyn Filter>>) -> Self {
self.filters.push(filter.into());
self
}
pub fn diagnostic(mut self, diagnostic: impl Into<Box<dyn Diagnostic>>) -> Self {
self.diagnostics.push(diagnostic.into());
self
}
}
impl DispatchBuilder<true> {
fn build(self) -> Dispatch {
Dispatch::new(self.filters, self.diagnostics, self.appends)
}
}
impl<const APPEND: bool> DispatchBuilder<APPEND> {
pub fn append(mut self, append: impl Into<Box<dyn Append>>) -> DispatchBuilder<true> {
self.appends.push(append.into());
DispatchBuilder {
filters: self.filters,
diagnostics: self.diagnostics,
appends: self.appends,
}
}
}