1use std::borrow::Cow;
2
3use enumset::EnumSet;
4use relay_protocol::{Annotated, Array, Meta, Object, Value};
5use uuid::Uuid;
6
7use crate::processor::{
8 process_value, ProcessValue, ProcessingResult, ProcessingState, Processor, ValueType,
9};
10
11impl ProcessValue for String {
12 #[inline]
13 fn value_type(&self) -> EnumSet<ValueType> {
14 EnumSet::only(ValueType::String)
15 }
16
17 #[inline]
18 fn process_value<P>(
19 &mut self,
20 meta: &mut Meta,
21 processor: &mut P,
22 state: &ProcessingState<'_>,
23 ) -> ProcessingResult
24 where
25 P: Processor,
26 {
27 processor.process_string(self, meta, state)
28 }
29}
30
31impl ProcessValue for bool {
32 #[inline]
33 fn value_type(&self) -> EnumSet<ValueType> {
34 EnumSet::only(ValueType::Boolean)
35 }
36
37 #[inline]
38 fn process_value<P>(
39 &mut self,
40 meta: &mut Meta,
41 processor: &mut P,
42 state: &ProcessingState<'_>,
43 ) -> ProcessingResult
44 where
45 P: Processor,
46 {
47 processor.process_bool(self, meta, state)
48 }
49}
50
51impl ProcessValue for u64 {
52 #[inline]
53 fn value_type(&self) -> EnumSet<ValueType> {
54 EnumSet::only(ValueType::Number)
55 }
56
57 #[inline]
58 fn process_value<P>(
59 &mut self,
60 meta: &mut Meta,
61 processor: &mut P,
62 state: &ProcessingState<'_>,
63 ) -> ProcessingResult
64 where
65 P: Processor,
66 {
67 processor.process_u64(self, meta, state)
68 }
69}
70
71impl ProcessValue for i64 {
72 #[inline]
73 fn value_type(&self) -> EnumSet<ValueType> {
74 EnumSet::only(ValueType::Number)
75 }
76
77 #[inline]
78 fn process_value<P>(
79 &mut self,
80 meta: &mut Meta,
81 processor: &mut P,
82 state: &ProcessingState<'_>,
83 ) -> ProcessingResult
84 where
85 P: Processor,
86 {
87 processor.process_i64(self, meta, state)
88 }
89}
90
91impl ProcessValue for f64 {
92 #[inline]
93 fn value_type(&self) -> EnumSet<ValueType> {
94 EnumSet::only(ValueType::Number)
95 }
96
97 #[inline]
98 fn process_value<P>(
99 &mut self,
100 meta: &mut Meta,
101 processor: &mut P,
102 state: &ProcessingState<'_>,
103 ) -> ProcessingResult
104 where
105 P: Processor,
106 {
107 processor.process_f64(self, meta, state)
108 }
109}
110
111impl ProcessValue for Uuid {}
112
113impl<T> ProcessValue for Array<T>
114where
115 T: ProcessValue,
116{
117 #[inline]
118 fn value_type(&self) -> EnumSet<ValueType> {
119 EnumSet::only(ValueType::Array)
120 }
121
122 #[inline]
123 fn process_value<P>(
124 &mut self,
125 meta: &mut Meta,
126 processor: &mut P,
127 state: &ProcessingState<'_>,
128 ) -> ProcessingResult
129 where
130 P: Processor,
131 {
132 processor.process_array(self, meta, state)
133 }
134
135 #[inline]
136 fn process_child_values<P>(
137 &mut self,
138 processor: &mut P,
139 state: &ProcessingState<'_>,
140 ) -> ProcessingResult
141 where
142 P: Processor,
143 {
144 for (index, element) in self.iter_mut().enumerate() {
145 process_value(
146 element,
147 processor,
148 &state.enter_index(index, state.inner_attrs(), ValueType::for_field(element)),
149 )?;
150 }
151
152 Ok(())
153 }
154}
155
156impl<T> ProcessValue for Object<T>
157where
158 T: ProcessValue,
159{
160 #[inline]
161 fn value_type(&self) -> EnumSet<ValueType> {
162 EnumSet::only(ValueType::Object)
163 }
164
165 #[inline]
166 fn process_value<P>(
167 &mut self,
168 meta: &mut Meta,
169 processor: &mut P,
170 state: &ProcessingState<'_>,
171 ) -> ProcessingResult
172 where
173 P: Processor,
174 {
175 processor.process_object(self, meta, state)
176 }
177
178 #[inline]
179 fn process_child_values<P>(
180 &mut self,
181 processor: &mut P,
182 state: &ProcessingState<'_>,
183 ) -> ProcessingResult
184 where
185 P: Processor,
186 {
187 for (k, v) in self.iter_mut() {
188 process_value(
189 v,
190 processor,
191 &state.enter_borrowed(k, state.inner_attrs(), ValueType::for_field(v)),
192 )?;
193 }
194
195 Ok(())
196 }
197}
198
199impl<T> ProcessValue for Box<T>
200where
201 T: ProcessValue,
202{
203 #[inline]
204 fn value_type(&self) -> EnumSet<ValueType> {
205 (**self).value_type()
206 }
207
208 #[inline]
209 fn process_value<P>(
210 &mut self,
211 meta: &mut Meta,
212 processor: &mut P,
213 state: &ProcessingState<'_>,
214 ) -> ProcessingResult
215 where
216 P: Processor,
217 {
218 ProcessValue::process_value(self.as_mut(), meta, processor, state)
219 }
220}
221
222macro_rules! process_tuple {
223 ($($name: ident),+) => {
224 impl< $( $name: ProcessValue ),* > ProcessValue for ( $( Annotated<$name>, )* ) {
225 #[inline]
226 fn value_type(&self) -> EnumSet<ValueType> { EnumSet::only(ValueType::Array) }
227
228 #[inline]
229 #[allow(non_snake_case, unused_assignments)]
230 fn process_child_values<P>(&mut self, processor: &mut P, state: &ProcessingState<'_>)
231 -> ProcessingResult
232 where
233 P: Processor,
234 {
235 let ($(ref mut $name,)*) = *self;
236 let mut index = 0;
237
238 $(
239 process_value($name, processor, &state.enter_index(index, state.inner_attrs(), ValueType::for_field($name)))?;
240 index += 1;
241 )*
242
243 Ok(())
244 }
245 }
246 };
247}
248
249process_tuple!(T1);
250process_tuple!(T1, T2);
251process_tuple!(T1, T2, T3);
252process_tuple!(T1, T2, T3, T4);
253process_tuple!(T1, T2, T3, T4, T5);
254process_tuple!(T1, T2, T3, T4, T5, T6);
255process_tuple!(T1, T2, T3, T4, T5, T6, T7);
256process_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);
257process_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
258process_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
259process_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
260process_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
261
262impl ProcessValue for Value {
263 fn value_type(&self) -> EnumSet<ValueType> {
264 match self {
265 Value::Bool(v) => v.value_type(),
266 Value::I64(v) => v.value_type(),
267 Value::U64(v) => v.value_type(),
268 Value::F64(v) => v.value_type(),
269 Value::String(v) => v.value_type(),
270 Value::Array(v) => v.value_type(),
271 Value::Object(v) => v.value_type(),
272 }
273 }
274
275 fn process_value<P>(
276 &mut self,
277 meta: &mut Meta,
278 processor: &mut P,
279 state: &ProcessingState<'_>,
280 ) -> ProcessingResult
281 where
282 P: Processor,
283 {
284 processor.process_value(self, meta, state)?;
285
286 let state = state.enter_nothing(Some(Cow::Borrowed(state.attrs())));
287 macro_rules! process_value {
288 ($v:ident) => {{
289 processor.before_process(Some(&*$v), meta, &state)?;
290 $v.process_value(meta, processor, &state)?;
291 processor.after_process(Some(&*$v), meta, &state)?;
292 }};
293 }
294
295 match self {
296 Value::Bool(v) => process_value!(v),
297 Value::I64(v) => process_value!(v),
298 Value::U64(v) => process_value!(v),
299 Value::F64(v) => process_value!(v),
300 Value::String(v) => process_value!(v),
301 Value::Array(v) => process_value!(v),
302 Value::Object(v) => process_value!(v),
303 }
304
305 Ok(())
306 }
307}