1use std::{any::Any, fmt, hash::Hash};
6
7use anyhow::{anyhow, bail, Result};
8use indexmap::{IndexMap, IndexSet};
9
10use super::Value;
11
12pub trait Node: fmt::Debug + Any {
17 fn visit_children(
25 &self,
26 _visitor: &mut dyn FnMut(&str, &dyn Node) -> Result<()>,
27 ) -> Result<()> {
28 Ok(())
29 }
30
31 fn visit_children_mut(
35 &mut self,
36 _visitor: &mut dyn FnMut(&str, &mut dyn Node) -> Result<()>,
37 ) -> Result<()> {
38 Ok(())
39 }
40
41 fn type_name(&self) -> Option<&'static str> {
45 None
46 }
47
48 fn take_into_value(&mut self) -> Value;
53
54 fn try_from_value(value: Value) -> Result<Self, FromValueError>
56 where
57 Self: Sized;
58
59 fn as_any(&self) -> &dyn Any;
63
64 fn as_any_mut(&mut self) -> &mut dyn Any;
66
67 fn to_box_any(self: Box<Self>) -> Box<dyn Any>;
68
69 fn visit<T: Node>(&self, mut visitor: impl FnMut(&T))
70 where
71 Self: Sized,
72 {
73 (self as &dyn Node)
75 .try_visit_descendents_recurse(&mut |node| {
76 visitor(node);
77 Ok(())
78 })
79 .unwrap()
80 }
81
82 fn visit_mut<T: Node>(&mut self, mut visitor: impl FnMut(&mut T))
83 where
84 Self: Sized,
85 {
86 (self as &mut dyn Node)
88 .try_visit_descendents_recurse_mut(&mut |node| {
89 visitor(node);
90 Ok(())
91 })
92 .unwrap()
93 }
94
95 fn try_visit<T: Node>(&self, mut visitor: impl FnMut(&T) -> Result<()>) -> Result<()>
96 where
97 Self: Sized,
98 {
99 (self as &dyn Node).try_visit_descendents_recurse(&mut visitor)
100 }
101
102 fn try_visit_mut<T: Node>(
103 &mut self,
104 mut visitor: impl FnMut(&mut T) -> Result<()>,
105 ) -> Result<()>
106 where
107 Self: Sized,
108 {
109 (self as &mut dyn Node).try_visit_descendents_recurse_mut(&mut visitor)
110 }
111
112 fn has_descendant<T: Node>(&self, mut matcher: impl FnMut(&T) -> bool) -> bool
114 where
115 Self: Sized,
116 {
117 self.try_visit(|node: &T| {
118 if matcher(node) {
119 bail!("");
123 } else {
124 Ok(())
125 }
126 })
127 .is_err()
128 }
129
130 fn has_descendant_with_type<T: Node>(&self) -> bool
132 where
133 Self: Sized,
134 {
135 self.has_descendant(|_: &T| true)
136 }
137
138 fn take(&mut self) -> Self
140 where
141 Self: Default,
142 {
143 std::mem::take(self)
144 }
145
146 fn try_from_node(mut other: impl Node) -> Result<Self>
148 where
149 Self: Sized,
150 {
151 Self::try_from_value(other.take_into_value()).map_err(|mut e| {
152 e.path.reverse();
153 let path = e.path.join("");
154 anyhow!("Node conversion error: {} (path: <root>{path})", e.message)
155 })
156 }
157}
158
159impl dyn Node {
160 pub(crate) fn try_visit_descendents_recurse<T: Node>(
161 &self,
162 visitor: &mut dyn FnMut(&T) -> Result<()>,
163 ) -> Result<()> {
164 if let Some(node) = self.as_any().downcast_ref::<T>() {
165 visitor(node)?;
166 }
167 self.visit_children(&mut |_, child| {
168 child.try_visit_descendents_recurse(visitor)?;
169 Ok(())
170 })
171 }
172
173 pub(crate) fn try_visit_descendents_recurse_mut<T: Node>(
174 &mut self,
175 visitor: &mut dyn FnMut(&mut T) -> Result<()>,
176 ) -> Result<()> {
177 if let Some(node) = self.as_any_mut().downcast_mut::<T>() {
178 visitor(node)?;
179 }
180 self.visit_children_mut(&mut |_, child| {
181 child.try_visit_descendents_recurse_mut(visitor)?;
182 Ok(())
183 })
184 }
185}
186
187pub struct FromValueError {
189 path: Vec<String>,
194 message: String,
195}
196
197impl FromValueError {
198 pub fn new(message: String) -> Self {
199 Self {
200 message,
201 path: vec![],
202 }
203 }
204
205 pub fn add_field_to_path(mut self, field: impl Into<String>) -> Self {
206 self.path.push(field.into());
207 self
208 }
209
210 pub fn into_anyhow(mut self) -> anyhow::Error {
211 self.path.reverse();
212 let path = self.path.join("");
213 anyhow!(
214 "Node conversion error: {} (path: <root>{path})",
215 self.message
216 )
217 }
218}
219
220macro_rules! simple_nodes {
221 ($($value_variant:ident($ty:ty)),* $(,)?) => {
222 $(
223 impl Node for $ty {
224 fn as_any(&self) -> &dyn Any {
225 self
226 }
227
228 fn as_any_mut(&mut self) -> &mut dyn Any {
229 self
230 }
231
232 fn to_box_any(self: Box<Self>) -> Box<dyn Any>{
233 self
234 }
235
236 fn take_into_value(&mut self) -> Value {
237 Value::$value_variant(self.take())
238 }
239
240 fn try_from_value(value: Value) -> Result<Self, FromValueError> {
241 match value {
242 Value::$value_variant(v) => Ok(v),
243 v => Err(FromValueError::new(format!(
244 "Node type error (expected {}, actual {v:?})",
245 std::stringify!($value_variant)
246 ))),
247 }
248 }
249 }
250 )*
251 };
252}
253
254simple_nodes!(
255 UInt8(u8),
256 Int8(i8),
257 UInt16(u16),
258 Int16(i16),
259 UInt32(u32),
260 Int32(i32),
261 UInt64(u64),
262 Int64(i64),
263 Float32(f32),
264 Float64(f64),
265 String(String),
266 Bool(bool),
267);
268
269impl<T: Node> Node for Box<T> {
270 fn visit_children(&self, visitor: &mut dyn FnMut(&str, &dyn Node) -> Result<()>) -> Result<()> {
271 visitor("", &**self)
272 }
273
274 fn visit_children_mut(
275 &mut self,
276 visitor: &mut dyn FnMut(&str, &mut dyn Node) -> Result<()>,
277 ) -> Result<()> {
278 visitor("", &mut **self)
279 }
280
281 fn as_any(&self) -> &dyn Any {
282 self
283 }
284
285 fn as_any_mut(&mut self) -> &mut dyn Any {
286 self
287 }
288
289 fn to_box_any(self: Box<Self>) -> Box<dyn Any> {
290 self
291 }
292
293 fn take_into_value(&mut self) -> Value {
294 (**self).take_into_value()
295 }
296
297 fn try_from_value(value: Value) -> Result<Self, FromValueError> {
298 T::try_from_value(value).map(Box::new)
299 }
300}
301
302impl<T: Node> Node for Option<T> {
303 fn visit_children(&self, visitor: &mut dyn FnMut(&str, &dyn Node) -> Result<()>) -> Result<()> {
304 if let Some(node) = self {
305 visitor("", node)?;
306 }
307 Ok(())
308 }
309
310 fn visit_children_mut(
311 &mut self,
312 visitor: &mut dyn FnMut(&str, &mut dyn Node) -> Result<()>,
313 ) -> Result<()> {
314 if let Some(node) = self {
315 visitor("", node)?;
316 }
317 Ok(())
318 }
319
320 fn as_any(&self) -> &dyn Any {
321 self
322 }
323
324 fn as_any_mut(&mut self) -> &mut dyn Any {
325 self
326 }
327
328 fn to_box_any(self: Box<Self>) -> Box<dyn Any> {
329 self
330 }
331
332 fn take_into_value(&mut self) -> Value {
333 Value::Option(
334 self.take()
335 .map(|mut node| node.take_into_value())
336 .map(Box::new),
337 )
338 }
339
340 fn try_from_value(value: Value) -> Result<Self, FromValueError> {
341 match value {
342 Value::Option(v) => v.map(|v| v.try_into_node()).transpose(),
343 v => Err(FromValueError::new(format!(
344 "Node type error (expected Option, actual {v:?})"
345 ))),
346 }
347 }
348}
349
350impl<T: Node> Node for Vec<T> {
351 fn visit_children(&self, visitor: &mut dyn FnMut(&str, &dyn Node) -> Result<()>) -> Result<()> {
352 for (i, child) in self.iter().enumerate() {
353 visitor(&format!(".{i}"), child)?;
354 }
355 Ok(())
356 }
357
358 fn visit_children_mut(
359 &mut self,
360 visitor: &mut dyn FnMut(&str, &mut dyn Node) -> Result<()>,
361 ) -> Result<()> {
362 for (i, child) in self.iter_mut().enumerate() {
363 visitor(&format!(".{i}"), child)?;
364 }
365 Ok(())
366 }
367
368 fn as_any(&self) -> &dyn Any {
369 self
370 }
371
372 fn as_any_mut(&mut self) -> &mut dyn Any {
373 self
374 }
375
376 fn to_box_any(self: Box<Self>) -> Box<dyn Any> {
377 self
378 }
379
380 fn take_into_value(&mut self) -> Value {
381 Value::Vec(
382 self.take()
383 .into_iter()
384 .map(|mut node| node.take_into_value())
385 .collect(),
386 )
387 }
388
389 fn try_from_value(value: Value) -> Result<Self, FromValueError> {
390 match value {
391 Value::Vec(values) => values
392 .into_iter()
393 .enumerate()
394 .map(|(i, v)| {
395 v.try_into_node()
396 .map_err(|e| e.add_field_to_path(format!("[{i}]")))
397 })
398 .collect(),
399 v => Err(FromValueError::new(format!(
400 "Node type error (expected Vec, actual {v:?})",
401 ))),
402 }
403 }
404}
405
406impl<T> Node for IndexSet<T>
407where
408 T: Node + Hash + Eq,
409{
410 fn visit_children(&self, visitor: &mut dyn FnMut(&str, &dyn Node) -> Result<()>) -> Result<()> {
411 for v in self.iter() {
412 visitor(&format!("{{{v:?}}}"), v)?;
413 }
414 Ok(())
415 }
416
417 fn visit_children_mut(
418 &mut self,
419 visitor: &mut dyn FnMut(&str, &mut dyn Node) -> Result<()>,
420 ) -> Result<()> {
421 *self = Node::take(self)
424 .into_iter()
425 .map(|mut v| {
426 visitor(&format!("{{{v:?}}}"), &mut v)?;
427 Ok(v)
428 })
429 .collect::<Result<IndexSet<_>>>()?;
430 Ok(())
431 }
432
433 fn as_any(&self) -> &dyn Any {
434 self
435 }
436
437 fn as_any_mut(&mut self) -> &mut dyn Any {
438 self
439 }
440
441 fn to_box_any(self: Box<Self>) -> Box<dyn Any> {
442 self
443 }
444
445 fn take_into_value(&mut self) -> Value {
446 Value::Set(
447 Node::take(self)
448 .into_iter()
449 .map(|mut node| node.take_into_value())
450 .collect(),
451 )
452 }
453
454 fn try_from_value(value: Value) -> Result<Self, FromValueError> {
455 match value {
456 Value::Set(values) => values
457 .into_iter()
458 .map(|k| {
459 let key_name = format!("{k:?}");
460 k.try_into_node()
461 .map_err(|e| e.add_field_to_path(format!("{{{key_name:?}}}")))
462 })
463 .collect(),
464 v => Err(FromValueError::new(format!(
465 "Node type error (expected Map, actual {v:?})",
466 ))),
467 }
468 }
469}
470
471impl<K, V> Node for IndexMap<K, V>
472where
473 K: Node + Hash + Eq,
474 V: Node,
475{
476 fn visit_children(&self, visitor: &mut dyn FnMut(&str, &dyn Node) -> Result<()>) -> Result<()> {
477 for (k, v) in self.iter() {
478 visitor(&format!("[{k:?}]"), v)?;
479 visitor(&format!(".key[{k:?}]"), k)?;
480 }
481 Ok(())
482 }
483
484 fn visit_children_mut(
485 &mut self,
486 visitor: &mut dyn FnMut(&str, &mut dyn Node) -> Result<()>,
487 ) -> Result<()> {
488 *self = self
491 .take()
492 .into_iter()
493 .map(|(mut k, mut v)| {
494 let key_name = format!("{k:?}");
495 visitor(&format!("{{{key_name:?}}}"), &mut k)?;
496 visitor(&format!("[{key_name:?}]"), &mut v)?;
497 Ok((k, v))
498 })
499 .collect::<Result<IndexMap<_, _>>>()?;
500 Ok(())
501 }
502
503 fn as_any(&self) -> &dyn Any {
504 self
505 }
506
507 fn as_any_mut(&mut self) -> &mut dyn Any {
508 self
509 }
510
511 fn to_box_any(self: Box<Self>) -> Box<dyn Any> {
512 self
513 }
514
515 fn take_into_value(&mut self) -> Value {
516 Value::Map(
517 self.take()
518 .into_iter()
519 .map(|(mut k, mut v)| (k.take_into_value(), v.take_into_value()))
520 .collect(),
521 )
522 }
523
524 fn try_from_value(value: Value) -> Result<Self, FromValueError> {
525 match value {
526 Value::Map(values) => values
527 .into_iter()
528 .map(|(k, v)| {
529 let v = v
530 .try_into_node()
531 .map_err(|e| e.add_field_to_path(format!("[{k:?}]")))?;
532 let k = k
533 .try_into_node()
534 .map_err(|e| e.add_field_to_path("[<key>]".to_string()))?;
535 Ok((k, v))
536 })
537 .collect(),
538 v => Err(FromValueError::new(format!(
539 "Node type error (expected Map, actual {v:?})",
540 ))),
541 }
542 }
543}