1use std::borrow::Cow;
2
3use serde_json::Value;
4
5use super::{Event, EventValue};
6
7#[derive(Debug, Clone)]
12pub struct KvEvent {
13 fields: Vec<(String, String)>,
14}
15
16impl KvEvent {
17 pub fn new(fields: Vec<(String, String)>) -> Self {
18 Self { fields }
19 }
20
21 pub fn fields(&self) -> &[(String, String)] {
22 &self.fields
23 }
24}
25
26impl Event for KvEvent {
27 fn get_field(&self, path: &str) -> Option<EventValue<'_>> {
28 self.fields
29 .iter()
30 .find(|(k, _)| k == path)
31 .map(|(_, v)| EventValue::Str(Cow::Borrowed(v.as_str())))
32 }
33
34 fn any_string_value(&self, pred: &dyn Fn(&str) -> bool) -> bool {
35 self.fields.iter().any(|(_, v)| pred(v.as_str()))
36 }
37
38 fn all_string_values(&self) -> Vec<Cow<'_, str>> {
39 self.fields
40 .iter()
41 .map(|(_, v)| Cow::Borrowed(v.as_str()))
42 .collect()
43 }
44
45 fn to_json(&self) -> Value {
46 let map: serde_json::Map<String, Value> = self
47 .fields
48 .iter()
49 .map(|(k, v)| (k.clone(), Value::String(v.clone())))
50 .collect();
51 Value::Object(map)
52 }
53
54 fn field_keys(&self) -> Vec<Cow<'_, str>> {
55 self.fields
56 .iter()
57 .map(|(k, _)| Cow::Borrowed(k.as_str()))
58 .collect()
59 }
60
61 fn top_level_keys(&self) -> Option<Vec<Cow<'_, str>>> {
62 Some(
63 self.fields
64 .iter()
65 .map(|(k, _)| Cow::Borrowed(k.as_str()))
66 .collect(),
67 )
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use serde_json::json;
75
76 #[test]
77 fn kv_get_field() {
78 let event = KvEvent::new(vec![
79 ("host".into(), "web01".into()),
80 ("status".into(), "200".into()),
81 ]);
82 assert_eq!(
83 event.get_field("host"),
84 Some(EventValue::Str(Cow::Borrowed("web01")))
85 );
86 assert_eq!(event.get_field("missing"), None);
87 }
88
89 #[test]
90 fn kv_all_string_values() {
91 let event = KvEvent::new(vec![("a".into(), "one".into()), ("b".into(), "two".into())]);
92 let vals = event.all_string_values();
93 assert_eq!(vals.len(), 2);
94 }
95
96 #[test]
97 fn kv_to_json() {
98 let event = KvEvent::new(vec![("key".into(), "val".into())]);
99 let j = event.to_json();
100 assert_eq!(j, json!({"key": "val"}));
101 }
102
103 #[test]
104 fn kv_field_keys() {
105 let event = KvEvent::new(vec![
106 ("host".into(), "web01".into()),
107 ("status".into(), "200".into()),
108 ]);
109 let keys: Vec<String> = event.field_keys().iter().map(|c| c.to_string()).collect();
110 assert_eq!(keys, vec!["host", "status"]);
111 }
112}