1use std::collections::BTreeMap;
2
3use crate::{encoding::Utf8Encoding, Event, EventVisitor, Path, PathSegment};
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>(&'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 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 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 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 pub fn as_string_mut(&mut self) -> Option<&mut String> {
88 match self {
89 Self::String(x) => Some(x),
90 _ => None,
91 }
92 }
93}