pub trait DrainMaker<Fr: Drain> {
type To;
fn make_from(self, drain: Fr) -> Self::To;
fn make(self) -> Self::To;
fn new() -> () {
()
}
fn filter<F>(self, f: F) -> FilterMaker<Self, F>
where Self: Sized,
F: 'static + Send + Sync + Fn(&Record) -> bool
{
FilterMaker {
inner: self,
filter_fn: f,
}
}
fn fuse(self) -> FuseMaker<Self>
where Self: Sized
{
FuseMaker(self)
}
fn discard(self) -> DiscardMaker<Self>
where Self: Sized
{
DiscardMaker(self)
}
}
impl<FrTo> DrainMaker<FrTo> for ()
where FrTo: Drain
{
type To = FrTo;
fn make_from(self, drain: FrTo) -> FrTo {
drain
}
fn make(self) -> FrTo {
unimplemented!()
}
}
pub struct FuseMaker<InnerMaker>(InnerMaker);
impl<Fr, InnerMaker> DrainMaker<Fr> for FuseMaker<InnerMaker>
where InnerMaker: DrainMaker<Fuse<Fr>>,
Fr: Drain,
<Fr as Drain>::Err: core::fmt::Display
{
type To = InnerMaker::To;
fn make_from(self, drain: Fr) -> Self::To {
self.0.make_from(Fuse::new(drain))
}
fn make(self) -> Self::To {
self.0.make_from(Fuse::new(Discard))
}
}
pub struct FilterMaker<InnerMaker, F>
where F: 'static + Send + Sync + Fn(&Record) -> bool
{
filter_fn: F,
inner: InnerMaker,
}
impl<Fr, InnerMaker, F> DrainMaker<Fr> for FilterMaker<InnerMaker, F>
where InnerMaker: DrainMaker<Filter<Fr>>,
Fr: Drain,
F: 'static + Send + Sync + Fn(&Record) -> bool
{
type To = InnerMaker::To;
fn make_from(self, drain: Fr) -> Self::To {
self.inner.make_from(Filter::new(drain, self.filter_fn))
}
fn make(self) -> Self::To {
self.inner.make_from(Discard)
}
}
pub struct DiscardMaker<InnerMaker>(InnerMaker);
impl<Fr, InnerMaker> DrainMaker<Fr> for DiscardMaker<InnerMaker>
where InnerMaker: DrainMaker<Discard>,
Fr: Drain
{
type To = InnerMaker::To;
fn make_from(self, drain: Fr) -> Self::To {
self.0.make_from(Discard)
}
fn make(self) -> Self::To {
self.0.make_from(Discard)
}
}
#[test]
fn maker() {
use {DrainMaker, Filter};
let drain = DrainMaker::new().fuse().filter(|_| true).discard().make();
let _log = Logger::root(drain, o!("version" => env!("CARGO_PKG_VERSION")));
}