1use std::collections::BTreeMap;
2
3use crate::{encoding::Utf8Encoding, Event, EventVisitor, Path, PathSegment, ScannerError};
4
5static FIRST_VISIT_KEY: &str = "message";
6
7#[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 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 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 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 pub fn as_string_mut(&mut self) -> Option<&mut String> {
91 match self {
92 Self::String(x) => Some(x),
93 _ => None,
94 }
95 }
96}