pub trait Drain: Send + Sync {
type Error;
fn log(&self, info: &Record, &OwnedKeyValueList) -> result::Result<(), Self::Error>;
}
impl<D: Drain+?Sized> Drain for Box<D> {
type Error = D::Error;
fn log(&self, info: &Record, o: &OwnedKeyValueList) -> result::Result<(), D::Error> {
(**self).log(info, o)
}
}
impl<D: Drain+?Sized> Drain for Arc<D> {
type Error = D::Error;
fn log(&self, info: &Record, o: &OwnedKeyValueList) -> result::Result<(), D::Error> {
(**self).log(info, o)
}
}
pub trait DrainExt: Sized + Drain {
fn map_err<F, E>(self, f : F) -> MapError<Self, E> where F : 'static + Sync + Send + Fn(<Self as Drain>::Error) -> E {
MapError::new(self, f)
}
fn ignore_err(self) -> IgnoreErr<Self> {
IgnoreErr::new(self)
}
fn fuse(self) -> Fuse<Self> where <Self as Drain>::Error : fmt::Display {
Fuse::new(self)
}
}
impl<D : Drain> DrainExt for D {}
pub struct Discard;
impl Drain for Discard {
type Error = Never;
fn log(&self, _: &Record, _: &OwnedKeyValueList) -> result::Result<(), Never> {
Ok(())
}
}
pub struct Filter<D: Drain> {
drain: D,
cond: Box<Fn(&Record) -> bool + 'static + Send + Sync>,
}
impl<D: Drain> Filter<D> {
pub fn new<F: 'static + Sync + Send + Fn(&Record) -> bool>(drain: D, cond: F) -> Self {
Filter {
drain: drain,
cond: Box::new(cond),
}
}
}
impl<D: Drain> Drain for Filter<D> {
type Error = D::Error;
fn log(&self,
info: &Record,
logger_values: &OwnedKeyValueList)
-> result::Result<(), Self::Error> {
if (self.cond)(&info) {
self.drain.log(info, logger_values)
} else {
Ok(())
}
}
}
pub struct MapError<D: Drain, E> {
drain: D,
map_fn: Box<(Fn(D::Error) -> E) + 'static+ Send+Sync>,
}
impl<D: Drain, E> MapError<D, E> {
pub fn new<F: 'static + Sync + Send + Fn(<D as Drain>::Error) -> E>(drain: D, map_fn: F) -> Self {
MapError {
drain: drain,
map_fn: Box::new(map_fn),
}
}
}
impl<D: Drain, E> Drain for MapError<D, E> {
type Error = E;
fn log(&self,
info: &Record,
logger_values: &OwnedKeyValueList)
-> result::Result<(), Self::Error> {
self.drain.log(info, logger_values).map_err(|e| (self.map_fn)(e))
}
}
pub struct LevelFilter<D: Drain> {
level: Level,
drain: D,
}
impl<D: Drain> LevelFilter<D> {
pub fn new(drain: D, level: Level) -> Self {
LevelFilter {
level: level,
drain: drain,
}
}
}
impl<D: Drain> Drain for LevelFilter<D> {
type Error = D::Error;
fn log(&self,
info: &Record,
logger_values: &OwnedKeyValueList)
-> result::Result<(), Self::Error> {
if info.level().is_at_least(self.level) {
self.drain.log(info, logger_values)
} else {
Ok(())
}
}
}
pub struct Duplicate<D1: Drain, D2: Drain> {
drain1: D1,
drain2: D2,
}
impl<D1: Drain, D2: Drain> Duplicate<D1, D2> {
pub fn new(drain1: D1, drain2: D2) -> Self {
Duplicate {
drain1: drain1,
drain2: drain2,
}
}
}
pub enum DuplicateError<E1, E2> {
First(E1),
Second(E2),
Both((E1, E2))
}
impl<E1 : fmt::Display, E2 : fmt::Display> fmt::Display for DuplicateError<E1, E2> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&DuplicateError::First(ref e) => write!(f, "{})", *e),
&DuplicateError::Second(ref e) => write!(f, "{})", *e),
&DuplicateError::Both((ref e1, ref e2)) => write!(f, "({}, {})", *e1, *e2),
}
}
}
impl<D1 : Drain, D2 : Drain> Drain for Duplicate<D1, D2> {
type Error = DuplicateError<D1::Error, D2::Error>;
fn log(&self,
info: &Record,
logger_values: &OwnedKeyValueList)
-> result::Result<(), Self::Error> {
let res1 = self.drain1.log(info, logger_values);
let res2 = self.drain2.log(info, logger_values);
match (res1, res2) {
(Ok(_), Ok(_)) => Ok(()),
(Err(e), Ok(_)) => Err(DuplicateError::First(e)),
(Ok(_), Err(e)) => Err(DuplicateError::Second(e)),
(Err(e1), Err(e2)) => Err(DuplicateError::Both((e1, e2))),
}
}
}
pub struct Fuse<D: Drain> {
drain: D,
}
impl<D: Drain> Fuse<D> {
pub fn new(drain: D) -> Self {
Fuse {
drain: drain,
}
}
}
impl<D: Drain> Drain for Fuse<D> where D::Error : fmt::Display {
type Error = Never;
fn log(&self,
info: &Record,
logger_values: &OwnedKeyValueList)
-> result::Result<(), Never> {
Ok(
self.drain.log(info, logger_values).unwrap_or_else(
|e| panic!("Fuse: {}", e)
)
)
}
}
pub struct IgnoreErr<D: Drain> {
drain: D,
}
impl<D: Drain> IgnoreErr<D> {
pub fn new(drain: D) -> Self {
IgnoreErr {
drain: drain,
}
}
}
impl<D: Drain> Drain for IgnoreErr<D> {
type Error = Never;
fn log(&self,
info: &Record,
logger_values: &OwnedKeyValueList)
-> result::Result<(), Never> {
let _ = self.drain.log(info, logger_values);
Ok(())
}
}
pub fn filter<D: Drain, F: 'static + Send + Sync + Fn(&Record) -> bool>(
cond: F,
d: D
) -> Filter<D> {
Filter::new(d, cond)
}
pub fn level_filter<D: Drain>(level: Level, d: D) -> LevelFilter<D> {
LevelFilter::new(d, level)
}
pub fn duplicate<D1: Drain, D2: Drain>(d1: D1, d2: D2) -> Duplicate<D1, D2> {
Duplicate::new(d1, d2)
}