rsigma_eval/event/
mapped.rs1use std::borrow::Cow;
17use std::collections::HashMap;
18
19use serde_json::Value;
20
21use super::{Event, EventValue};
22
23pub struct MappedEvent<'a, E: Event + ?Sized> {
26 inner: &'a E,
27 mapping: &'a HashMap<String, Vec<String>>,
31}
32
33impl<'a, E: Event + ?Sized> MappedEvent<'a, E> {
34 pub fn new(inner: &'a E, mapping: &'a HashMap<String, Vec<String>>) -> Self {
37 Self { inner, mapping }
38 }
39}
40
41impl<E: Event + ?Sized> Event for MappedEvent<'_, E> {
42 fn get_field(&self, path: &str) -> Option<EventValue<'_>> {
43 if let Some(targets) = self.mapping.get(path) {
44 for target in targets {
45 if let Some(value) = self.inner.get_field(target) {
46 return Some(value);
47 }
48 }
49 return self.inner.get_field(path);
52 }
53 self.inner.get_field(path)
54 }
55
56 fn any_string_value(&self, pred: &dyn Fn(&str) -> bool) -> bool {
57 self.inner.any_string_value(pred)
58 }
59
60 fn all_string_values(&self) -> Vec<Cow<'_, str>> {
61 self.inner.all_string_values()
62 }
63
64 fn to_json(&self) -> Value {
65 self.inner.to_json()
66 }
67
68 fn field_keys(&self) -> Vec<Cow<'_, str>> {
69 self.inner.field_keys()
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use crate::event::JsonEvent;
77 use serde_json::json;
78
79 fn map(pairs: &[(&str, &[&str])]) -> HashMap<String, Vec<String>> {
80 pairs
81 .iter()
82 .map(|(k, vs)| {
83 (
84 (*k).to_string(),
85 vs.iter().map(|s| (*s).to_string()).collect(),
86 )
87 })
88 .collect()
89 }
90
91 #[test]
92 fn remaps_field_to_schema_name() {
93 let v = json!({"user": {"name": "alice"}});
94 let inner = JsonEvent::borrow(&v);
95 let m = map(&[("User", &["user.name"])]);
96 let mapped = MappedEvent::new(&inner, &m);
97 assert_eq!(
98 mapped
99 .get_field("User")
100 .and_then(|x| x.as_str().map(|s| s.to_string())),
101 Some("alice".to_string())
102 );
103 }
104
105 #[test]
106 fn falls_back_to_original_name_when_unmapped() {
107 let v = json!({"User": "bob"});
108 let inner = JsonEvent::borrow(&v);
109 let m = HashMap::new();
111 let mapped = MappedEvent::new(&inner, &m);
112 assert_eq!(
113 mapped
114 .get_field("User")
115 .and_then(|x| x.as_str().map(|s| s.to_string())),
116 Some("bob".to_string())
117 );
118 }
119
120 #[test]
121 fn one_to_many_picks_first_present() {
122 let v = json!({"source": {"user": {"name": "carol"}}});
123 let inner = JsonEvent::borrow(&v);
124 let m = map(&[("User", &["user.name", "source.user.name"])]);
125 let mapped = MappedEvent::new(&inner, &m);
126 assert_eq!(
127 mapped
128 .get_field("User")
129 .and_then(|x| x.as_str().map(|s| s.to_string())),
130 Some("carol".to_string())
131 );
132 }
133}