use crate::{LogLevel, LogRecord, Vault, VaultError};
pub trait Filter {
fn apply(&mut self, record: LogRecord) -> Option<LogRecord>;
}
pub struct MinimumLevel {
minimum: LogLevel,
}
impl MinimumLevel {
#[must_use]
pub const fn new(minimum: LogLevel) -> Self {
Self { minimum }
}
}
impl Filter for MinimumLevel {
fn apply(&mut self, record: LogRecord) -> Option<LogRecord> {
(record.level >= self.minimum).then_some(record)
}
}
pub struct AddField {
key: String,
value: String,
}
impl AddField {
#[must_use]
pub fn new(key: impl Into<String>, value: impl Into<String>) -> Self {
Self {
key: key.into(),
value: value.into(),
}
}
}
impl Filter for AddField {
fn apply(&mut self, mut record: LogRecord) -> Option<LogRecord> {
record.fields.insert(self.key.clone(), self.value.clone());
Some(record)
}
}
pub struct Pipeline {
vault: Vault,
filters: Vec<Box<dyn Filter>>,
}
impl Pipeline {
#[must_use]
pub fn new(vault: Vault) -> Self {
Self {
vault,
filters: Vec::new(),
}
}
pub fn add_filter(&mut self, filter: impl Filter + 'static) {
self.filters.push(Box::new(filter));
}
pub fn process(&mut self, mut record: LogRecord) -> Result<Option<u64>, VaultError> {
for filter in &mut self.filters {
let Some(filtered) = filter.apply(record) else {
return Ok(None);
};
record = filtered;
}
self.vault.append(record).map(Some)
}
#[must_use]
pub const fn vault(&self) -> &Vault {
&self.vault
}
#[must_use]
pub const fn vault_mut(&mut self) -> &mut Vault {
&mut self.vault
}
#[must_use]
pub fn into_vault(self) -> Vault {
self.vault
}
}