use serde;
use super::prelude::*;
pub trait Logging {
fn raw_msg(&self, severity: Severity, msg: &str) -> io::Result<Option<ContextWriter>>;
}
pub trait LoggingExt
where
Self: Sized,
{
fn msg(&self, severity: Severity, msg: &str);
fn debug(&self, msg: &str);
fn info(&self, msg: &str);
fn warn(&self, msg: &str);
fn error(&self, msg: &str);
fn set<'a, V: 'a + serde::Serialize>(&'a self, key: &'a str, value: V)
-> ContextLog<'a, V, Self>;
}
impl<T: Logging> LoggingExt for T {
fn msg(&self, severity: Severity, msg: &str) {
if let Err(err) = self.raw_msg(severity, msg) {
eprint!("[bflog] error writing log message - {}", err);
}
}
fn debug(&self, msg: &str) {
self.msg(Severity::Debug, msg)
}
fn info(&self, msg: &str) {
self.msg(Severity::Info, msg)
}
fn warn(&self, msg: &str) {
self.msg(Severity::Warn, msg)
}
fn error(&self, msg: &str) {
self.msg(Severity::Error, msg)
}
fn set<'a, V: 'a + serde::Serialize>(
&'a self,
key: &'a str,
value: V,
) -> ContextLog<'a, V, Self> {
ContextLog::new(self, key, value)
}
}
pub struct ContextLog<'a, V: 'a, L: 'a> {
key: &'a str,
value: V,
inner: &'a L,
}
impl<'a, V: 'a + serde::Serialize, L: 'a + Logging> ContextLog<'a, V, L> {
pub fn new(log: &'a L, key: &'a str, value: V) -> ContextLog<'a, V, L> {
ContextLog {
key,
value,
inner: log,
}
}
}
impl<'a, V: 'a + serde::Serialize, L: 'a + Logging> Logging for ContextLog<'a, V, L> {
fn raw_msg(&self, severity: Severity, msg: &str) -> io::Result<Option<ContextWriter>> {
match self.inner.raw_msg(severity, msg) {
Ok(Some(mut context)) => {
let key = self.key;
let value = &self.value;
context.write(key, value)?;
Ok(Some(context))
}
x => x,
}
}
}