shape/
visitor.rs

1use crate::case_enum::all::All;
2use crate::case_enum::one::One;
3use crate::location::Located;
4use crate::{Error, NamedShapePathKey, Shape, ShapeCase};
5use indexmap::IndexMap;
6
7#[expect(unused_variables, clippy::missing_errors_doc)]
8pub trait ShapeVisitor<Output = ()> {
9    type Error: std::error::Error;
10    type Output;
11
12    fn default(&mut self, shape: &Shape) -> Result<Self::Output, Self::Error>;
13
14    fn visit_bool(
15        &mut self,
16        shape: &Shape,
17        value: &Option<bool>,
18    ) -> Result<Self::Output, Self::Error> {
19        self.default(shape)
20    }
21
22    fn visit_string(
23        &mut self,
24        shape: &Shape,
25        value: &Option<String>,
26    ) -> Result<Self::Output, Self::Error> {
27        self.default(shape)
28    }
29
30    fn visit_int(
31        &mut self,
32        shape: &Shape,
33        value: &Option<i64>,
34    ) -> Result<Self::Output, Self::Error> {
35        self.default(shape)
36    }
37
38    fn visit_float(&mut self, shape: &Shape) -> Result<Self::Output, Self::Error> {
39        self.default(shape)
40    }
41
42    fn visit_null(&mut self, shape: &Shape) -> Result<Self::Output, Self::Error> {
43        self.default(shape)
44    }
45
46    fn visit_array(
47        &mut self,
48        shape: &Shape,
49        prefix: &[Shape],
50        tail: &Shape,
51    ) -> Result<Self::Output, Self::Error> {
52        self.default(shape)
53    }
54
55    fn visit_object(
56        &mut self,
57        shape: &Shape,
58        fields: &IndexMap<String, Shape>,
59        rest: &Shape,
60    ) -> Result<Self::Output, Self::Error> {
61        self.default(shape)
62    }
63
64    fn visit_one(&mut self, shape: &Shape, one: &One) -> Result<Self::Output, Self::Error> {
65        self.default(shape)
66    }
67
68    fn visit_name(
69        &mut self,
70        shape: &Shape,
71        name: &Located<String>,
72        subpath: &[Located<NamedShapePathKey>],
73    ) -> Result<Self::Output, Self::Error> {
74        self.default(shape)
75    }
76
77    fn visit_unknown(&mut self, shape: &Shape) -> Result<Self::Output, Self::Error> {
78        self.default(shape)
79    }
80
81    fn visit_none(&mut self, shape: &Shape) -> Result<Self::Output, Self::Error> {
82        self.default(shape)
83    }
84
85    fn visit_error(&mut self, shape: &Shape, err: &Error) -> Result<Self::Output, Self::Error> {
86        self.default(shape)
87    }
88
89    fn visit_all(&mut self, shape: &Shape, all: &All) -> Result<Self::Output, Self::Error> {
90        self.default(shape)
91    }
92}
93
94impl Shape {
95    #[expect(clippy::missing_errors_doc)]
96    pub fn visit_shape<V: ShapeVisitor>(&self, visitor: &mut V) -> Result<V::Output, V::Error> {
97        match self.case.as_ref() {
98            ShapeCase::Bool(b) => visitor.visit_bool(self, b),
99            ShapeCase::String(s) => visitor.visit_string(self, s),
100            ShapeCase::Int(i) => visitor.visit_int(self, i),
101            ShapeCase::Float => visitor.visit_float(self),
102            ShapeCase::Null => visitor.visit_null(self),
103            ShapeCase::Array { prefix, tail } => visitor.visit_array(self, prefix, tail),
104            ShapeCase::Object { fields, rest } => visitor.visit_object(self, fields, rest),
105            ShapeCase::One(one) => visitor.visit_one(self, one),
106            ShapeCase::All(all) => visitor.visit_all(self, all),
107            ShapeCase::Name(name, subpath) => visitor.visit_name(self, name, subpath),
108            ShapeCase::Unknown => visitor.visit_unknown(self),
109            ShapeCase::None => visitor.visit_none(self),
110            ShapeCase::Error(err) => visitor.visit_error(self, err),
111        }
112    }
113}