use crate::Append;
use crate::Error;
use crate::Filter;
use crate::Layout;
use crate::append;
use crate::core::DispatchBuilder;
use crate::core::LoggerBuilder;
use crate::filter::env_filter::EnvFilterBuilder;
pub struct LogStarterBuilder {
builder: LoggerBuilder,
}
pub fn builder() -> LogStarterBuilder {
use crate::core::builder;
LogStarterBuilder { builder: builder() }
}
impl LogStarterBuilder {
pub fn dispatch<F>(mut self, f: F) -> Self
where
F: FnOnce(DispatchBuilder<false>) -> DispatchBuilder<true>,
{
self.builder = self.builder.dispatch(f);
self
}
pub fn try_apply(self) -> Result<(), Error> {
self.builder
.try_apply()
.map_err(|_| Error::new("logforth default logger has been already setup"))?;
logforth_bridge_log::try_setup()
.map_err(|_| Error::new("log global logger has been already setup"))?;
Ok(())
}
pub fn apply(self) {
self.try_apply()
.expect("LogStarterBuilder::apply must be called before the global logger initialized");
}
}
enum StdStream {
Stdout(append::Stdout),
Stderr(append::Stderr),
}
pub struct LogStarterStdStreamBuilder {
append: StdStream,
filter: Box<dyn Filter>,
layout: Box<dyn Layout>,
}
pub fn stdout() -> LogStarterStdStreamBuilder {
LogStarterStdStreamBuilder {
append: StdStream::Stdout(append::Stdout::default()),
filter: default_filter(),
layout: default_layout(),
}
}
pub fn stderr() -> LogStarterStdStreamBuilder {
LogStarterStdStreamBuilder {
append: StdStream::Stderr(append::Stderr::default()),
filter: default_filter(),
layout: default_layout(),
}
}
fn default_filter() -> Box<dyn Filter> {
Box::new(EnvFilterBuilder::from_default_env().build())
}
fn default_layout() -> Box<dyn Layout> {
#[cfg(feature = "layout-text")]
{
use crate::layout::TextLayout;
Box::new(TextLayout::default())
}
#[cfg(not(feature = "layout-text"))]
{
use crate::layout::PlainTextLayout;
Box::new(PlainTextLayout::default())
}
}
impl LogStarterStdStreamBuilder {
pub fn layout(mut self, layout: impl Into<Box<dyn Layout>>) -> Self {
self.layout = layout.into();
self
}
pub fn filter(mut self, filter: impl Into<Box<dyn Filter>>) -> Self {
self.filter = filter.into();
self
}
pub fn try_apply(self) -> Result<(), Error> {
let Self {
append,
filter,
layout,
} = self;
let append: Box<dyn Append> = match append {
StdStream::Stdout(a) => Box::new(a.with_layout(layout)),
StdStream::Stderr(a) => Box::new(a.with_layout(layout)),
};
builder()
.dispatch(|d| d.filter(filter).append(append))
.try_apply()
}
pub fn apply(self) {
self.try_apply().expect(
"LogStarterStdStreamBuilder::apply must be called before the global logger initialized",
);
}
}