Skip to main content

rsigma_eval/event/
plain.rs

1use std::borrow::Cow;
2
3use serde_json::Value;
4
5use super::{Event, EventValue};
6
7/// Raw log line event (keyword matching only).
8///
9/// `get_field` always returns `None`. Useful for keyword-only Sigma rules.
10#[derive(Debug, Clone)]
11pub struct PlainEvent {
12    raw: String,
13}
14
15impl PlainEvent {
16    pub fn new(raw: String) -> Self {
17        Self { raw }
18    }
19
20    pub fn raw(&self) -> &str {
21        &self.raw
22    }
23}
24
25impl Event for PlainEvent {
26    fn get_field(&self, _path: &str) -> Option<EventValue<'_>> {
27        None
28    }
29
30    fn any_string_value(&self, pred: &dyn Fn(&str) -> bool) -> bool {
31        pred(&self.raw)
32    }
33
34    fn all_string_values(&self) -> Vec<Cow<'_, str>> {
35        vec![Cow::Borrowed(&self.raw)]
36    }
37
38    fn to_json(&self) -> Value {
39        serde_json::json!({ "_raw": self.raw })
40    }
41
42    /// Plain log lines have no structured field surface; the synthetic
43    /// `_raw` envelope from `to_json` is not a field operators care about
44    /// for coverage analysis.
45    fn field_keys(&self) -> Vec<Cow<'_, str>> {
46        Vec::new()
47    }
48
49    fn top_level_keys(&self) -> Option<Vec<Cow<'_, str>>> {
50        Some(Vec::new())
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57    use serde_json::json;
58
59    #[test]
60    fn plain_get_field_always_none() {
61        let event = PlainEvent::new("raw log line".into());
62        assert_eq!(event.get_field("anything"), None);
63    }
64
65    #[test]
66    fn plain_keyword_search() {
67        let event = PlainEvent::new("error: disk full".into());
68        assert!(event.any_string_value(&|s| s.contains("disk")));
69        assert!(!event.any_string_value(&|s| s.contains("memory")));
70    }
71
72    #[test]
73    fn plain_field_keys_is_empty() {
74        let event = PlainEvent::new("error: disk full".into());
75        assert!(event.field_keys().is_empty());
76    }
77
78    #[test]
79    fn plain_to_json() {
80        let event = PlainEvent::new("hello".into());
81        assert_eq!(event.to_json(), json!({"_raw": "hello"}));
82    }
83}