lex_core/lex/ast/
traits.rs1use super::elements::ContentItem;
7use super::elements::VerbatimLine;
8use super::range::{Position, Range};
9use super::text_content::TextContent;
10
11pub trait Visitor {
31 fn visit_session(&mut self, _session: &super::Session) {}
33 fn leave_session(&mut self, _session: &super::Session) {}
34
35 fn visit_definition(&mut self, _definition: &super::Definition) {}
36 fn leave_definition(&mut self, _definition: &super::Definition) {}
37
38 fn visit_list(&mut self, _list: &super::List) {}
39 fn leave_list(&mut self, _list: &super::List) {}
40
41 fn visit_list_item(&mut self, _list_item: &super::ListItem) {}
42 fn leave_list_item(&mut self, _list_item: &super::ListItem) {}
43
44 fn visit_paragraph(&mut self, _paragraph: &super::Paragraph) {}
46 fn leave_paragraph(&mut self, _paragraph: &super::Paragraph) {}
47
48 fn visit_text_line(&mut self, _text_line: &super::elements::paragraph::TextLine) {}
49 fn leave_text_line(&mut self, _text_line: &super::elements::paragraph::TextLine) {}
50
51 fn visit_verbatim_block(&mut self, _verbatim_block: &super::Verbatim) {}
52 fn leave_verbatim_block(&mut self, _verbatim_block: &super::Verbatim) {}
53
54 fn visit_verbatim_group(&mut self, _group: &super::elements::verbatim::VerbatimGroupItemRef) {}
55 fn leave_verbatim_group(&mut self, _group: &super::elements::verbatim::VerbatimGroupItemRef) {}
56
57 fn visit_verbatim_line(&mut self, _verbatim_line: &VerbatimLine) {}
58 fn leave_verbatim_line(&mut self, _verbatim_line: &VerbatimLine) {}
59
60 fn visit_annotation(&mut self, _annotation: &super::Annotation) {}
61 fn leave_annotation(&mut self, _annotation: &super::Annotation) {}
62
63 fn visit_blank_line_group(
64 &mut self,
65 _blank_line_group: &super::elements::blank_line_group::BlankLineGroup,
66 ) {
67 }
68 fn leave_blank_line_group(
69 &mut self,
70 _blank_line_group: &super::elements::blank_line_group::BlankLineGroup,
71 ) {
72 }
73}
74
75pub fn visit_children(visitor: &mut dyn Visitor, items: &[ContentItem]) {
77 for item in items {
78 item.accept(visitor);
79 }
80}
81
82pub trait AstNode {
84 fn node_type(&self) -> &'static str;
85 fn display_label(&self) -> String;
86 fn range(&self) -> &Range;
87 fn start_position(&self) -> Position {
88 self.range().start
89 }
90
91 fn accept(&self, visitor: &mut dyn Visitor);
93}
94
95pub trait Container: AstNode {
97 fn label(&self) -> &str;
98 fn children(&self) -> &[ContentItem];
99 fn children_mut(&mut self) -> &mut Vec<ContentItem>;
100}
101
102pub trait TextNode: AstNode {
104 fn text(&self) -> String;
105 fn lines(&self) -> &[TextContent];
106}
107
108pub trait VisualStructure: AstNode {
114 fn is_source_line_node(&self) -> bool {
119 false
120 }
121
122 fn has_visual_header(&self) -> bool {
127 false
128 }
129
130 fn collapses_with_children(&self) -> bool {
136 false
137 }
138}
139
140#[cfg(test)]
141mod tests {
142 use super::super::elements::{Paragraph, Session};
143 use super::*;
144
145 #[test]
146 fn test_visitor_traversal() {
147 let para = Paragraph::from_line("Hello, World!".to_string());
149 let session = Session::with_title("Test Session".to_string());
150
151 struct CountingVisitor {
153 session_count: usize,
154 paragraph_count: usize,
155 text_line_count: usize,
156 }
157
158 impl Visitor for CountingVisitor {
159 fn visit_session(&mut self, _: &super::super::Session) {
160 self.session_count += 1;
161 }
162 fn visit_paragraph(&mut self, _: &super::super::Paragraph) {
163 self.paragraph_count += 1;
164 }
165 fn visit_text_line(&mut self, _: &super::super::elements::paragraph::TextLine) {
166 self.text_line_count += 1;
167 }
168 }
169
170 let mut visitor = CountingVisitor {
171 session_count: 0,
172 paragraph_count: 0,
173 text_line_count: 0,
174 };
175
176 para.accept(&mut visitor);
178 assert_eq!(visitor.paragraph_count, 1);
179 assert_eq!(visitor.text_line_count, 1); assert_eq!(visitor.session_count, 0);
181
182 visitor.session_count = 0;
184 visitor.paragraph_count = 0;
185 visitor.text_line_count = 0;
186 session.accept(&mut visitor);
187 assert_eq!(visitor.session_count, 1);
188 assert_eq!(visitor.paragraph_count, 0); }
190}