Skip to main content

rsigma_eval/event/
map.rs

1use std::borrow::Cow;
2use std::collections::HashMap;
3
4use serde_json::Value;
5
6use super::{Event, EventValue};
7
8/// Generic flat-map event for user-defined key-value stores.
9///
10/// Flat key lookup only (no dot-notation, no nesting).
11#[derive(Debug, Clone)]
12pub struct MapEvent<K = String, V = String>
13where
14    K: AsRef<str> + std::fmt::Debug + Clone,
15    V: AsRef<str> + std::fmt::Debug + Clone,
16{
17    inner: HashMap<K, V>,
18}
19
20impl<K, V> MapEvent<K, V>
21where
22    K: AsRef<str> + std::fmt::Debug + Clone,
23    V: AsRef<str> + std::fmt::Debug + Clone,
24{
25    pub fn new(inner: HashMap<K, V>) -> Self {
26        Self { inner }
27    }
28}
29
30impl<K, V> Event for MapEvent<K, V>
31where
32    K: AsRef<str> + std::fmt::Debug + Clone,
33    V: AsRef<str> + std::fmt::Debug + Clone,
34{
35    fn get_field(&self, path: &str) -> Option<EventValue<'_>> {
36        self.inner
37            .iter()
38            .find(|(k, _)| k.as_ref() == path)
39            .map(|(_, v)| EventValue::Str(Cow::Borrowed(v.as_ref())))
40    }
41
42    fn any_string_value(&self, pred: &dyn Fn(&str) -> bool) -> bool {
43        self.inner.values().any(|v| pred(v.as_ref()))
44    }
45
46    fn all_string_values(&self) -> Vec<Cow<'_, str>> {
47        self.inner
48            .values()
49            .map(|v| Cow::Borrowed(v.as_ref()))
50            .collect()
51    }
52
53    fn to_json(&self) -> Value {
54        let map: serde_json::Map<String, Value> = self
55            .inner
56            .iter()
57            .map(|(k, v)| {
58                (
59                    k.as_ref().to_string(),
60                    Value::String(v.as_ref().to_string()),
61                )
62            })
63            .collect();
64        Value::Object(map)
65    }
66
67    fn field_keys(&self) -> Vec<Cow<'_, str>> {
68        self.inner
69            .keys()
70            .map(|k| Cow::Borrowed(k.as_ref()))
71            .collect()
72    }
73}
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78    use serde_json::json;
79
80    #[test]
81    fn map_event_get_field() {
82        let mut m = HashMap::new();
83        m.insert("user".to_string(), "admin".to_string());
84        let event = MapEvent::new(m);
85        assert_eq!(
86            event.get_field("user"),
87            Some(EventValue::Str(Cow::Borrowed("admin")))
88        );
89        assert_eq!(event.get_field("missing"), None);
90    }
91
92    #[test]
93    fn map_event_to_json() {
94        let mut m = HashMap::new();
95        m.insert("k".to_string(), "v".to_string());
96        let event = MapEvent::new(m);
97        assert_eq!(event.to_json(), json!({"k": "v"}));
98    }
99
100    #[test]
101    fn map_event_field_keys() {
102        let mut m = HashMap::new();
103        m.insert("user".to_string(), "admin".to_string());
104        m.insert("host".to_string(), "web01".to_string());
105        let event = MapEvent::new(m);
106        let mut keys: Vec<String> = event.field_keys().iter().map(|c| c.to_string()).collect();
107        keys.sort();
108        assert_eq!(keys, vec!["host", "user"]);
109    }
110}