1use crate::encoding::{Encoding, Utf8Encoding};
2use crate::path::Path;
3use crate::PathSegment;
4
5pub trait Event: Sized {
9 type Encoding: Encoding;
11
12 fn visit_event<'a>(&'a mut self, visitor: &mut impl EventVisitor<'a>);
14
15 fn visit_string_mut(&mut self, path: &Path, visit: impl FnMut(&mut String) -> bool);
19}
20
21pub trait EventVisitor<'path> {
22 fn push_segment(&mut self, segment: PathSegment<'path>);
23 fn pop_segment(&mut self);
24 fn visit_string<'s>(&'s mut self, value: &str) -> VisitStringResult<'s, 'path>;
25}
26
27pub struct VisitStringResult<'s, 'path> {
28 pub might_mutate: bool,
31 pub path: &'s Path<'path>,
32}
33
34impl Event for String {
35 type Encoding = Utf8Encoding;
36
37 fn visit_event<'path>(&'path mut self, visitor: &mut impl EventVisitor<'path>) {
38 let _result = visitor.visit_string(self);
39 }
40
41 fn visit_string_mut(&mut self, _path: &Path, mut visit: impl FnMut(&mut String) -> bool) {
42 (visit)(self);
43 }
44}
45
46#[cfg(test)]
47pub(crate) mod test {
48 use crate::simple_event::SimpleEvent;
49
50 use super::*;
51
52 #[derive(Debug, PartialEq, Eq)]
53 enum VisitOp {
54 Push(PathSegment<'static>),
55 Pop,
56 Visit(String),
57 }
58
59 struct Visitor {
60 path: Path<'static>,
61 ops: Vec<VisitOp>,
62 }
63
64 impl<'path> EventVisitor<'path> for Visitor {
65 fn push_segment(&mut self, segment: PathSegment<'path>) {
66 self.ops.push(VisitOp::Push(segment.into_static()));
67 }
68
69 fn pop_segment(&mut self) {
70 self.ops.push(VisitOp::Pop);
71 }
72
73 fn visit_string<'s>(&'s mut self, value: &str) -> VisitStringResult<'s, 'path> {
74 self.ops.push(VisitOp::Visit(value.to_string()));
75 VisitStringResult {
76 might_mutate: true,
77 path: &self.path,
78 }
79 }
80 }
81
82 #[test]
83 pub fn test_string_event() {
84 let value = "sdsisthebest";
85 let mut visitor = Visitor {
86 ops: vec![],
87 path: Path::root(),
88 };
89 value.to_string().visit_event(&mut visitor);
90 assert_eq!(visitor.ops, vec![VisitOp::Visit(value.into()),]);
91 }
92
93 #[test]
94 pub fn test_simple_event() {
95 let mut event = SimpleEvent::Map(
96 [
97 (
98 "key-a".to_string(),
99 SimpleEvent::String("value-a".to_string()),
100 ),
101 (
102 "key-b".to_string(),
103 SimpleEvent::Map(
104 [(
105 "key-b-1".to_string(),
106 SimpleEvent::String("value-b-1".to_string()),
107 )]
108 .into(),
109 ),
110 ),
111 ]
112 .into(),
113 );
114
115 let mut visitor = Visitor {
116 ops: vec![],
117 path: Path::root(),
118 };
119 event.visit_event(&mut visitor);
120
121 assert_eq!(
122 visitor.ops,
123 vec![
124 VisitOp::Push(PathSegment::Field("key-a".into())),
125 VisitOp::Visit("value-a".into()),
126 VisitOp::Pop,
127 VisitOp::Push(PathSegment::Field("key-b".into())),
128 VisitOp::Push(PathSegment::Field("key-b-1".into())),
129 VisitOp::Visit("value-b-1".into()),
130 VisitOp::Pop,
131 VisitOp::Pop,
132 ]
133 );
134 }
135}