1use std::borrow::Cow;
2
3use enumset::EnumSet;
4use relay_protocol::{Annotated, Array, FiniteF64, Meta, Object, Value};
5use uuid::Uuid;
6
7use crate::processor::{
8 ProcessValue, ProcessingResult, ProcessingState, Processor, ValueType, process_value,
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 FiniteF64 {
112 #[inline]
113 fn value_type(&self) -> EnumSet<ValueType> {
114 EnumSet::only(ValueType::Number)
115 }
116
117 #[inline]
118 fn process_value<P>(
119 &mut self,
120 meta: &mut Meta,
121 processor: &mut P,
122 state: &ProcessingState<'_>,
123 ) -> ProcessingResult
124 where
125 P: Processor,
126 {
127 processor.process_finite_f64(self, meta, state)
128 }
129}
130
131impl ProcessValue for Uuid {}
132
133impl<T> ProcessValue for Array<T>
134where
135 T: ProcessValue,
136{
137 #[inline]
138 fn value_type(&self) -> EnumSet<ValueType> {
139 EnumSet::only(ValueType::Array)
140 }
141
142 #[inline]
143 fn process_value<P>(
144 &mut self,
145 meta: &mut Meta,
146 processor: &mut P,
147 state: &ProcessingState<'_>,
148 ) -> ProcessingResult
149 where
150 P: Processor,
151 {
152 processor.process_array(self, meta, state)
153 }
154
155 #[inline]
156 fn process_child_values<P>(
157 &mut self,
158 processor: &mut P,
159 state: &ProcessingState<'_>,
160 ) -> ProcessingResult
161 where
162 P: Processor,
163 {
164 for (index, element) in self.iter_mut().enumerate() {
165 process_value(
166 element,
167 processor,
168 &state.enter_index(index, state.inner_attrs(), ValueType::for_field(element)),
169 )?;
170 }
171
172 Ok(())
173 }
174}
175
176impl<T> ProcessValue for Object<T>
177where
178 T: ProcessValue,
179{
180 #[inline]
181 fn value_type(&self) -> EnumSet<ValueType> {
182 EnumSet::only(ValueType::Object)
183 }
184
185 #[inline]
186 fn process_value<P>(
187 &mut self,
188 meta: &mut Meta,
189 processor: &mut P,
190 state: &ProcessingState<'_>,
191 ) -> ProcessingResult
192 where
193 P: Processor,
194 {
195 processor.process_object(self, meta, state)
196 }
197
198 #[inline]
199 fn process_child_values<P>(
200 &mut self,
201 processor: &mut P,
202 state: &ProcessingState<'_>,
203 ) -> ProcessingResult
204 where
205 P: Processor,
206 {
207 for (k, v) in self.iter_mut() {
208 process_value(
209 v,
210 processor,
211 &state.enter_borrowed(k, state.inner_attrs(), ValueType::for_field(v)),
212 )?;
213 }
214
215 Ok(())
216 }
217}
218
219impl<T> ProcessValue for Box<T>
220where
221 T: ProcessValue,
222{
223 #[inline]
224 fn value_type(&self) -> EnumSet<ValueType> {
225 (**self).value_type()
226 }
227
228 #[inline]
229 fn process_value<P>(
230 &mut self,
231 meta: &mut Meta,
232 processor: &mut P,
233 state: &ProcessingState<'_>,
234 ) -> ProcessingResult
235 where
236 P: Processor,
237 {
238 ProcessValue::process_value(self.as_mut(), meta, processor, state)
239 }
240}
241
242macro_rules! process_tuple {
243 ($($name: ident),+) => {
244 impl< $( $name: ProcessValue ),* > ProcessValue for ( $( Annotated<$name>, )* ) {
245 #[inline]
246 fn value_type(&self) -> EnumSet<ValueType> { EnumSet::only(ValueType::Array) }
247
248 #[inline]
249 #[allow(non_snake_case, unused_assignments)]
250 fn process_child_values<P>(&mut self, processor: &mut P, state: &ProcessingState<'_>)
251 -> ProcessingResult
252 where
253 P: Processor,
254 {
255 let ($(ref mut $name,)*) = *self;
256 let mut index = 0;
257
258 $(
259 process_value($name, processor, &state.enter_index(index, state.inner_attrs(), ValueType::for_field($name)))?;
260 index += 1;
261 )*
262
263 Ok(())
264 }
265 }
266 };
267}
268
269process_tuple!(T1);
270process_tuple!(T1, T2);
271process_tuple!(T1, T2, T3);
272process_tuple!(T1, T2, T3, T4);
273process_tuple!(T1, T2, T3, T4, T5);
274process_tuple!(T1, T2, T3, T4, T5, T6);
275process_tuple!(T1, T2, T3, T4, T5, T6, T7);
276process_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);
277process_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
278process_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
279process_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
280process_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
281
282impl ProcessValue for Value {
283 fn value_type(&self) -> EnumSet<ValueType> {
284 match self {
285 Value::Bool(v) => v.value_type(),
286 Value::I64(v) => v.value_type(),
287 Value::U64(v) => v.value_type(),
288 Value::F64(v) => v.value_type(),
289 Value::String(v) => v.value_type(),
290 Value::Array(v) => v.value_type(),
291 Value::Object(v) => v.value_type(),
292 }
293 }
294
295 fn process_value<P>(
296 &mut self,
297 meta: &mut Meta,
298 processor: &mut P,
299 state: &ProcessingState<'_>,
300 ) -> ProcessingResult
301 where
302 P: Processor,
303 {
304 processor.process_value(self, meta, state)?;
305
306 let state = state.enter_nothing(Some(Cow::Borrowed(state.attrs())));
307 macro_rules! process_value {
308 ($v:ident) => {{
309 processor.before_process(Some(&*$v), meta, &state)?;
310 $v.process_value(meta, processor, &state)?;
311 processor.after_process(Some(&*$v), meta, &state)?;
312 }};
313 }
314
315 match self {
316 Value::Bool(v) => process_value!(v),
317 Value::I64(v) => process_value!(v),
318 Value::U64(v) => process_value!(v),
319 Value::F64(v) => process_value!(v),
320 Value::String(v) => process_value!(v),
321 Value::Array(v) => process_value!(v),
322 Value::Object(v) => process_value!(v),
323 }
324
325 Ok(())
326 }
327}