pub type Filter = (&'static str, Option<::log::LevelFilter>);
pub struct Filters(pub &'static [Filter]);
impl Filters {
pub fn is_enabled(&self, metadata: &::log::Metadata) -> bool {
if self.0.is_empty() {
true
} else if let Some(idx) = self
.0
.iter()
.position(|&(target, _)| target == metadata.target())
{
let (_, lvl) = self.0[idx];
lvl.is_none() || lvl.filter(|lvl| metadata.level() <= *lvl).is_some()
} else {
false
}
}
}
#[cfg(test)]
mod tests {
use super::Filters;
use log::{Level, LevelFilter};
fn metadata(level: Level, target: &'static str) -> ::log::Metadata<'static> {
::log::Metadata::builder()
.level(level)
.target(target)
.build()
}
const ALL_LEVELS: [Level; 5] = [
Level::Error,
Level::Warn,
Level::Info,
Level::Debug,
Level::Trace,
];
#[test]
fn empty_always_enabled() {
let filters = Filters(&[]);
ALL_LEVELS.iter().for_each(|level| {
assert!(filters.is_enabled(&metadata(*level, "foobar")));
});
}
#[test]
fn no_level_always_true() {
let filters = Filters(&[("barbaz", None), ("foobar", None)]);
ALL_LEVELS
.iter()
.for_each(|level| assert!(filters.is_enabled(&metadata(*level, "foobar"))));
}
#[test]
fn module_level() {
let filters = Filters(&[
("barbaz", Some(LevelFilter::Error)),
("foobar", Some(LevelFilter::Info)),
]);
ALL_LEVELS
.iter()
.filter(|level| **level <= LevelFilter::Info)
.for_each(|level| {
assert!(filters.is_enabled(&metadata(*level, "foobar")), "{}", level)
});
ALL_LEVELS
.iter()
.filter(|level| **level > LevelFilter::Info)
.for_each(|level| {
assert!(
!filters.is_enabled(&metadata(*level, "foobar")),
"{}",
level
)
});
ALL_LEVELS
.iter()
.filter(|level| **level != Level::Error)
.for_each(|level| {
assert!(
!filters.is_enabled(&metadata(*level, "barbaz")),
"{}",
level
)
});
assert!(filters.is_enabled(&metadata(Level::Error, "barbaz")));
}
}