]> git.proxmox.com Git - rustc.git/blob - vendor/toml_edit/src/visit.rs
New upstream version 1.76.0+dfsg1
[rustc.git] / vendor / toml_edit / src / visit.rs
1 #![allow(missing_docs)]
2
3 //! Document tree traversal to walk a shared borrow of a document tree.
4 //!
5 //! Each method of the [`Visit`] trait is a hook that can be overridden
6 //! to customize the behavior when mutating the corresponding type of node.
7 //! By default, every method recursively visits the substructure of the
8 //! input by invoking the right visitor method of each of its fields.
9 //!
10 //! ```
11 //! # use toml_edit::{Item, ArrayOfTables, Table, Value};
12 //!
13 //! pub trait Visit<'doc> {
14 //! /* ... */
15 //!
16 //! fn visit_item(&mut self, i: &'doc Item) {
17 //! visit_item(self, i);
18 //! }
19 //!
20 //! /* ... */
21 //! # fn visit_value(&mut self, i: &'doc Value);
22 //! # fn visit_table(&mut self, i: &'doc Table);
23 //! # fn visit_array_of_tables(&mut self, i: &'doc ArrayOfTables);
24 //! }
25 //!
26 //! pub fn visit_item<'doc, V>(v: &mut V, node: &'doc Item)
27 //! where
28 //! V: Visit<'doc> + ?Sized,
29 //! {
30 //! match node {
31 //! Item::None => {}
32 //! Item::Value(value) => v.visit_value(value),
33 //! Item::Table(table) => v.visit_table(table),
34 //! Item::ArrayOfTables(array) => v.visit_array_of_tables(array),
35 //! }
36 //! }
37 //! ```
38 //!
39 //! The API is modeled after [`syn::visit`](https://docs.rs/syn/1/syn/visit).
40 //!
41 //! # Examples
42 //!
43 //! This visitor stores every string in the document.
44 //!
45 //! ```
46 //! # #[cfg(feature = "parse")] {
47 //! # use toml_edit::*;
48 //! use toml_edit::visit::*;
49 //!
50 //! #[derive(Default)]
51 //! struct StringCollector<'doc> {
52 //! strings: Vec<&'doc str>,
53 //! }
54 //!
55 //! impl<'doc> Visit<'doc> for StringCollector<'doc> {
56 //! fn visit_string(&mut self, node: &'doc Formatted<String>) {
57 //! self.strings.push(node.value().as_str());
58 //! }
59 //! }
60 //!
61 //! let input = r#"
62 //! laputa = "sky-castle"
63 //! the-force = { value = "surrounds-you" }
64 //! "#;
65 //!
66 //! let mut document: Document = input.parse().unwrap();
67 //! let mut visitor = StringCollector::default();
68 //! visitor.visit_document(&document);
69 //!
70 //! assert_eq!(visitor.strings, vec!["sky-castle", "surrounds-you"]);
71 //! # }
72 //! ```
73 //!
74 //! For a more complex example where the visitor has internal state, see `examples/visit.rs`
75 //! [on GitHub](https://github.com/toml-rs/toml/blob/main/crates/toml_edit/examples/visit.rs).
76
77 use crate::{
78 Array, ArrayOfTables, Datetime, Document, Formatted, InlineTable, Item, Table, TableLike, Value,
79 };
80
81 /// Document tree traversal to mutate an exclusive borrow of a document tree in-place.
82 ///
83 /// See the [module documentation](self) for details.
84 pub trait Visit<'doc> {
85 fn visit_document(&mut self, node: &'doc Document) {
86 visit_document(self, node);
87 }
88
89 fn visit_item(&mut self, node: &'doc Item) {
90 visit_item(self, node);
91 }
92
93 fn visit_table(&mut self, node: &'doc Table) {
94 visit_table(self, node);
95 }
96
97 fn visit_inline_table(&mut self, node: &'doc InlineTable) {
98 visit_inline_table(self, node)
99 }
100
101 fn visit_table_like(&mut self, node: &'doc dyn TableLike) {
102 visit_table_like(self, node);
103 }
104
105 fn visit_table_like_kv(&mut self, key: &'doc str, node: &'doc Item) {
106 visit_table_like_kv(self, key, node);
107 }
108
109 fn visit_array(&mut self, node: &'doc Array) {
110 visit_array(self, node);
111 }
112
113 fn visit_array_of_tables(&mut self, node: &'doc ArrayOfTables) {
114 visit_array_of_tables(self, node);
115 }
116
117 fn visit_value(&mut self, node: &'doc Value) {
118 visit_value(self, node);
119 }
120
121 fn visit_boolean(&mut self, node: &'doc Formatted<bool>) {
122 visit_boolean(self, node)
123 }
124
125 fn visit_datetime(&mut self, node: &'doc Formatted<Datetime>) {
126 visit_datetime(self, node);
127 }
128
129 fn visit_float(&mut self, node: &'doc Formatted<f64>) {
130 visit_float(self, node)
131 }
132
133 fn visit_integer(&mut self, node: &'doc Formatted<i64>) {
134 visit_integer(self, node)
135 }
136
137 fn visit_string(&mut self, node: &'doc Formatted<String>) {
138 visit_string(self, node)
139 }
140 }
141
142 pub fn visit_document<'doc, V>(v: &mut V, node: &'doc Document)
143 where
144 V: Visit<'doc> + ?Sized,
145 {
146 v.visit_table(node.as_table());
147 }
148
149 pub fn visit_item<'doc, V>(v: &mut V, node: &'doc Item)
150 where
151 V: Visit<'doc> + ?Sized,
152 {
153 match node {
154 Item::None => {}
155 Item::Value(value) => v.visit_value(value),
156 Item::Table(table) => v.visit_table(table),
157 Item::ArrayOfTables(array) => v.visit_array_of_tables(array),
158 }
159 }
160
161 pub fn visit_table<'doc, V>(v: &mut V, node: &'doc Table)
162 where
163 V: Visit<'doc> + ?Sized,
164 {
165 v.visit_table_like(node)
166 }
167
168 pub fn visit_inline_table<'doc, V>(v: &mut V, node: &'doc InlineTable)
169 where
170 V: Visit<'doc> + ?Sized,
171 {
172 v.visit_table_like(node)
173 }
174
175 pub fn visit_table_like<'doc, V>(v: &mut V, node: &'doc dyn TableLike)
176 where
177 V: Visit<'doc> + ?Sized,
178 {
179 for (key, item) in node.iter() {
180 v.visit_table_like_kv(key, item)
181 }
182 }
183
184 pub fn visit_table_like_kv<'doc, V>(v: &mut V, _key: &'doc str, node: &'doc Item)
185 where
186 V: Visit<'doc> + ?Sized,
187 {
188 v.visit_item(node)
189 }
190
191 pub fn visit_array<'doc, V>(v: &mut V, node: &'doc Array)
192 where
193 V: Visit<'doc> + ?Sized,
194 {
195 for value in node.iter() {
196 v.visit_value(value);
197 }
198 }
199
200 pub fn visit_array_of_tables<'doc, V>(v: &mut V, node: &'doc ArrayOfTables)
201 where
202 V: Visit<'doc> + ?Sized,
203 {
204 for table in node.iter() {
205 v.visit_table(table);
206 }
207 }
208
209 pub fn visit_value<'doc, V>(v: &mut V, node: &'doc Value)
210 where
211 V: Visit<'doc> + ?Sized,
212 {
213 match node {
214 Value::String(s) => v.visit_string(s),
215 Value::Integer(i) => v.visit_integer(i),
216 Value::Float(f) => v.visit_float(f),
217 Value::Boolean(b) => v.visit_boolean(b),
218 Value::Datetime(dt) => v.visit_datetime(dt),
219 Value::Array(array) => v.visit_array(array),
220 Value::InlineTable(table) => v.visit_inline_table(table),
221 }
222 }
223
224 macro_rules! empty_visit {
225 ($name: ident, $t: ty) => {
226 fn $name<'doc, V>(_v: &mut V, _node: &'doc $t)
227 where
228 V: Visit<'doc> + ?Sized,
229 {
230 }
231 };
232 }
233
234 empty_visit!(visit_boolean, Formatted<bool>);
235 empty_visit!(visit_datetime, Formatted<Datetime>);
236 empty_visit!(visit_float, Formatted<f64>);
237 empty_visit!(visit_integer, Formatted<i64>);
238 empty_visit!(visit_string, Formatted<String>);