Remove repetitive code by abstracting it

With this patch, the log level aggregation is abstracted away by using
zero sized types and a macro to implement the whole thing.

This does not alter functionality, but makes the code more readable.

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
Matthias Beyer 2018-11-06 19:39:41 +01:00
parent 1ff1d85428
commit 09f0968755

View file

@ -88,34 +88,12 @@ impl ImagLogger {
::libimaginteraction::format::register_all_format_helpers(&mut handlebars); ::libimaginteraction::format::register_all_format_helpers(&mut handlebars);
{ {
let fmt = aggregate_global_format_trace(config)?; use self::log_lvl_aggregate::*;
handlebars.register_template_string("TRACE", fmt) let _ = aggregate::<Trace>(&mut handlebars, config, "TRACE")?;
.map_err(Error::from) let _ = aggregate::<Debug>(&mut handlebars, config, "DEBUG")?;
.context(err_msg("Handlebars template error"))?; // name must be uppercase let _ = aggregate::<Info>(&mut handlebars, config, "INFO")?;
} let _ = aggregate::<Warn>(&mut handlebars, config, "WARN")?;
{ let _ = aggregate::<Error>(&mut handlebars, config, "ERROR")?;
let fmt = aggregate_global_format_debug(config)?;
handlebars.register_template_string("DEBUG", fmt)
.map_err(Error::from)
.context(err_msg("Handlebars template error"))?; // name must be uppercase
}
{
let fmt = aggregate_global_format_info(config)?;
handlebars.register_template_string("INFO", fmt)
.map_err(Error::from)
.context(err_msg("Handlebars template error"))?; // name must be uppercase
}
{
let fmt = aggregate_global_format_warn(config)?;
handlebars.register_template_string("WARN", fmt)
.map_err(Error::from)
.context(err_msg("Handlebars template error"))?; // name must be uppercase
}
{
let fmt = aggregate_global_format_error(config)?;
handlebars.register_template_string("ERROR", fmt)
.map_err(Error::from)
.context(err_msg("Handlebars template error"))?; // name must be uppercase
} }
Ok(ImagLogger { Ok(ImagLogger {
@ -335,54 +313,55 @@ fn aggregate_global_destinations(matches: &ArgMatches, config: Option<&Value>)
} }
} }
macro_rules! aggregate_global_format { mod log_lvl_aggregate {
($read_str:expr, $error_msg_if_missing:expr, $config:expr) => { use failure::Fallible as Result;
try!($config.ok_or_else(|| Error::from(err_msg($error_msg_if_missing)))) use failure::Error as E;
use failure::ResultExt;
use failure::err_msg;
use toml::Value;
use toml_query::read::TomlValueReadTypeExt;
use handlebars::Handlebars;
use libimagerror::errors::ErrorMsg as EM;
macro_rules! aggregate_global_format_with {
($t:ident, $read_str:expr) => {
pub struct $t;
impl LogLevelAggregator for $t {
fn aggregate(config: Option<&Value>) -> Result<String> {
config.ok_or_else(|| {
E::from(err_msg(concat!("Config missing: Logging format: ", stringify!($t))))
})?
.read_string($read_str) .read_string($read_str)
.map_err(Error::from) .map_err(E::from)
.context(EM::TomlQueryError)? .context(EM::TomlQueryError)?
.ok_or_else(|| Error::from(err_msg($error_msg_if_missing))) .ok_or_else(|| {
E::from(err_msg(concat!("Config missing: Logging format: ", stringify!($t))))
})
}
}
}; };
} }
fn aggregate_global_format_trace(config: Option<&Value>) pub trait LogLevelAggregator {
-> Result<String> fn aggregate(config: Option<&Value>) -> Result<String>;
{ }
aggregate_global_format!("imag.logging.format.trace",
"Config missing: Logging format: Trace",
config)
}
fn aggregate_global_format_debug(config: Option<&Value>) pub fn aggregate<T: LogLevelAggregator>(hb: &mut Handlebars, config: Option<&Value>, lvlstr: &str)
-> Result<String> -> Result<()>
{ {
aggregate_global_format!("imag.logging.format.debug", hb.register_template_string(lvlstr, T::aggregate(config)?)
"Config missing: Logging format: Debug", .map_err(E::from)
config) .context(err_msg("Handlebars template error"))
} .map_err(E::from)
}
fn aggregate_global_format_info(config: Option<&Value>) aggregate_global_format_with!(Trace, "imag.logging.format.trace");
-> Result<String> aggregate_global_format_with!(Debug, "imag.logging.format.debug");
{ aggregate_global_format_with!(Info, "imag.logging.format.info");
aggregate_global_format!("imag.logging.format.info", aggregate_global_format_with!(Warn, "imag.logging.format.warn");
"Config missing: Logging format: Info", aggregate_global_format_with!(Error, "imag.logging.format.error");
config)
}
fn aggregate_global_format_warn(config: Option<&Value>)
-> Result<String>
{
aggregate_global_format!("imag.logging.format.warn",
"Config missing: Logging format: Warn",
config)
}
fn aggregate_global_format_error(config: Option<&Value>)
-> Result<String>
{
aggregate_global_format!("imag.logging.format.error",
"Config missing: Logging format: Error",
config)
} }
fn aggregate_module_settings(_matches: &ArgMatches, config: Option<&Value>) fn aggregate_module_settings(_matches: &ArgMatches, config: Option<&Value>)