use rsigma_parser::LogSource;
use crate::event::Event;
#[derive(Debug, Clone)]
pub struct LogSourceExtractor {
product_field: String,
service_field: String,
category_field: String,
defaults: LogSource,
}
impl LogSourceExtractor {
pub fn new() -> Self {
LogSourceExtractor {
product_field: "product".to_string(),
service_field: "service".to_string(),
category_field: "category".to_string(),
defaults: LogSource::default(),
}
}
#[must_use]
pub fn with_field_names(
mut self,
product_field: impl Into<String>,
service_field: impl Into<String>,
category_field: impl Into<String>,
) -> Self {
self.product_field = product_field.into();
self.service_field = service_field.into();
self.category_field = category_field.into();
self
}
#[must_use]
pub fn with_defaults(mut self, defaults: LogSource) -> Self {
self.defaults = defaults;
self
}
pub fn extract<E: Event>(&self, event: &E) -> LogSource {
LogSource {
product: self.resolve(event, &self.product_field, &self.defaults.product),
service: self.resolve(event, &self.service_field, &self.defaults.service),
category: self.resolve(event, &self.category_field, &self.defaults.category),
..LogSource::default()
}
}
fn resolve<E: Event>(
&self,
event: &E,
field: &str,
default: &Option<String>,
) -> Option<String> {
if let Some(value) = event.get_field(field)
&& let Some(s) = value.as_str()
{
let trimmed = s.trim();
if !trimmed.is_empty() {
return Some(trimmed.to_string());
}
}
default.clone()
}
}
impl Default for LogSourceExtractor {
fn default() -> Self {
Self::new()
}
}