dd_sds/
simple_event.rs

1use std::collections::BTreeMap;
2
3use crate::{encoding::Utf8Encoding, Event, EventVisitor, Path, PathSegment};
4
5static FIRST_VISIT_KEY: &str = "message";
6
7/// A simple implementation of `Event`. This is meant for testing / demonstration purposes.
8/// It always start visiting elements with key == "message" first, then the rest of the keys in the map
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub enum SimpleEvent {
11    String(String),
12    List(Vec<SimpleEvent>),
13    Map(BTreeMap<String, SimpleEvent>),
14}
15
16impl Event for SimpleEvent {
17    type Encoding = Utf8Encoding;
18
19    fn visit_event<'path>(&'path mut self, visitor: &mut impl EventVisitor<'path>) {
20        match self {
21            Self::String(value) => {
22                let _result = visitor.visit_string(value);
23            }
24            Self::List(list) => {
25                for (i, child) in list.iter_mut().enumerate() {
26                    visitor.push_segment(PathSegment::Index(i));
27                    child.visit_event(visitor);
28                    visitor.pop_segment();
29                }
30            }
31            Self::Map(map) => {
32                // Create a data structure holding the key that will be processed after the message key
33                let mut key_to_post_process: Vec<(&String, &mut SimpleEvent)> = vec![];
34                for (key, child) in map.iter_mut() {
35                    if key == FIRST_VISIT_KEY {
36                        visitor.push_segment(key.as_str().into());
37                        child.visit_event(visitor);
38                        visitor.pop_segment();
39                    } else {
40                        key_to_post_process.push((key, child));
41                    }
42                }
43                for (key, child) in key_to_post_process {
44                    visitor.push_segment(key.as_str().into());
45                    child.visit_event(visitor);
46                    visitor.pop_segment();
47                }
48            }
49        }
50    }
51
52    fn visit_string_mut(&mut self, path: &Path, mut visit: impl FnMut(&mut String) -> bool) {
53        let mut value = self;
54
55        for segment in &path.segments {
56            match segment {
57                PathSegment::Field(key) => {
58                    value = value.as_map_mut().unwrap().get_mut(key.as_ref()).unwrap();
59                }
60                PathSegment::Index(i) => {
61                    value = value.as_list_mut().unwrap().get_mut(*i).unwrap();
62                }
63            }
64        }
65        (visit)(value.as_string_mut().unwrap());
66    }
67}
68
69impl SimpleEvent {
70    /// Gets a mutable reference to the list.
71    pub fn as_list_mut(&mut self) -> Option<&mut Vec<SimpleEvent>> {
72        match self {
73            Self::List(x) => Some(x),
74            _ => None,
75        }
76    }
77
78    /// Gets a mutable reference to the map.
79    pub fn as_map_mut(&mut self) -> Option<&mut BTreeMap<String, SimpleEvent>> {
80        match self {
81            Self::Map(x) => Some(x),
82            _ => None,
83        }
84    }
85
86    /// Gets a mutable reference to the map.
87    pub fn as_string_mut(&mut self) -> Option<&mut String> {
88        match self {
89            Self::String(x) => Some(x),
90            _ => None,
91        }
92    }
93}