dd_sds/
simple_event.rs

1use std::collections::BTreeMap;
2
3use crate::{encoding::Utf8Encoding, Event, EventVisitor, Path, PathSegment, ScannerError};
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>(
20        &'path mut self,
21        visitor: &mut impl EventVisitor<'path>,
22    ) -> Result<(), ScannerError> {
23        match self {
24            Self::String(value) => visitor.visit_string(value).map(|_| {}),
25            Self::List(list) => {
26                for (i, child) in list.iter_mut().enumerate() {
27                    visitor.push_segment(PathSegment::Index(i));
28                    child.visit_event(visitor)?;
29                    visitor.pop_segment();
30                }
31                Ok(())
32            }
33            Self::Map(map) => {
34                // Create a data structure holding the key that will be processed after the message key
35                let mut key_to_post_process: Vec<(&String, &mut SimpleEvent)> = vec![];
36                for (key, child) in map.iter_mut() {
37                    if key == FIRST_VISIT_KEY {
38                        visitor.push_segment(key.as_str().into());
39                        child.visit_event(visitor)?;
40                        visitor.pop_segment();
41                    } else {
42                        key_to_post_process.push((key, child));
43                    }
44                }
45                for (key, child) in key_to_post_process {
46                    visitor.push_segment(key.as_str().into());
47                    child.visit_event(visitor)?;
48                    visitor.pop_segment();
49                }
50                Ok(())
51            }
52        }
53    }
54
55    fn visit_string_mut(&mut self, path: &Path, mut visit: impl FnMut(&mut String) -> bool) {
56        let mut value = self;
57
58        for segment in &path.segments {
59            match segment {
60                PathSegment::Field(key) => {
61                    value = value.as_map_mut().unwrap().get_mut(key.as_ref()).unwrap();
62                }
63                PathSegment::Index(i) => {
64                    value = value.as_list_mut().unwrap().get_mut(*i).unwrap();
65                }
66            }
67        }
68        (visit)(value.as_string_mut().unwrap());
69    }
70}
71
72impl SimpleEvent {
73    /// Gets a mutable reference to the list.
74    pub fn as_list_mut(&mut self) -> Option<&mut Vec<SimpleEvent>> {
75        match self {
76            Self::List(x) => Some(x),
77            _ => None,
78        }
79    }
80
81    /// Gets a mutable reference to the map.
82    pub fn as_map_mut(&mut self) -> Option<&mut BTreeMap<String, SimpleEvent>> {
83        match self {
84            Self::Map(x) => Some(x),
85            _ => None,
86        }
87    }
88
89    /// Gets a mutable reference to the map.
90    pub fn as_string_mut(&mut self) -> Option<&mut String> {
91        match self {
92            Self::String(x) => Some(x),
93            _ => None,
94        }
95    }
96}