1use crate::{
2 ast::{OperationVisitor, OperationVisitorContext},
3 static_graphql::query::*,
4 validation::utils::ValidationErrorContext,
5};
6
7pub type ValidationVisitor<'doc> = Box<dyn OperationVisitor<'doc, ValidationErrorContext> + 'doc>;
8
9pub struct ValidationVisitors<'doc> {
10 visitors: Vec<ValidationVisitor<'doc>>,
11}
12
13impl<'doc> ValidationVisitors<'doc> {
14 pub fn new(visitors: impl IntoIterator<Item = ValidationVisitor<'doc>>) -> Self {
15 Self {
16 visitors: visitors.into_iter().collect(),
17 }
18 }
19
20 pub fn is_empty(&self) -> bool {
21 self.visitors.is_empty()
22 }
23}
24
25impl<'doc> OperationVisitor<'doc, ValidationErrorContext> for ValidationVisitors<'doc> {
26 fn enter_document(
27 &mut self,
28 context: &mut OperationVisitorContext<'doc>,
29 errors: &mut ValidationErrorContext,
30 document: &'doc Document,
31 ) {
32 for visitor in &mut self.visitors {
33 visitor.enter_document(context, errors, document);
34 }
35 }
36
37 fn leave_document(
38 &mut self,
39 context: &mut OperationVisitorContext<'doc>,
40 errors: &mut ValidationErrorContext,
41 document: &Document,
42 ) {
43 for visitor in &mut self.visitors {
44 visitor.leave_document(context, errors, document);
45 }
46 }
47
48 fn enter_operation_definition(
49 &mut self,
50 context: &mut OperationVisitorContext<'doc>,
51 errors: &mut ValidationErrorContext,
52 operation: &'doc OperationDefinition,
53 ) {
54 for visitor in &mut self.visitors {
55 visitor.enter_operation_definition(context, errors, operation);
56 }
57 }
58
59 fn leave_operation_definition(
60 &mut self,
61 context: &mut OperationVisitorContext<'doc>,
62 errors: &mut ValidationErrorContext,
63 operation: &OperationDefinition,
64 ) {
65 for visitor in &mut self.visitors {
66 visitor.leave_operation_definition(context, errors, operation);
67 }
68 }
69
70 fn enter_fragment_definition(
71 &mut self,
72 context: &mut OperationVisitorContext<'doc>,
73 errors: &mut ValidationErrorContext,
74 fragment: &'doc FragmentDefinition,
75 ) {
76 for visitor in &mut self.visitors {
77 visitor.enter_fragment_definition(context, errors, fragment);
78 }
79 }
80
81 fn leave_fragment_definition(
82 &mut self,
83 context: &mut OperationVisitorContext<'doc>,
84 errors: &mut ValidationErrorContext,
85 fragment: &FragmentDefinition,
86 ) {
87 for visitor in &mut self.visitors {
88 visitor.leave_fragment_definition(context, errors, fragment);
89 }
90 }
91
92 fn enter_variable_definition(
93 &mut self,
94 context: &mut OperationVisitorContext<'doc>,
95 errors: &mut ValidationErrorContext,
96 variable: &'doc VariableDefinition,
97 ) {
98 for visitor in &mut self.visitors {
99 visitor.enter_variable_definition(context, errors, variable);
100 }
101 }
102
103 fn leave_variable_definition(
104 &mut self,
105 context: &mut OperationVisitorContext<'doc>,
106 errors: &mut ValidationErrorContext,
107 variable: &VariableDefinition,
108 ) {
109 for visitor in &mut self.visitors {
110 visitor.leave_variable_definition(context, errors, variable);
111 }
112 }
113
114 fn enter_directive(
115 &mut self,
116 context: &mut OperationVisitorContext<'doc>,
117 errors: &mut ValidationErrorContext,
118 directive: &Directive,
119 ) {
120 for visitor in &mut self.visitors {
121 visitor.enter_directive(context, errors, directive);
122 }
123 }
124
125 fn leave_directive(
126 &mut self,
127 context: &mut OperationVisitorContext<'doc>,
128 errors: &mut ValidationErrorContext,
129 directive: &Directive,
130 ) {
131 for visitor in &mut self.visitors {
132 visitor.leave_directive(context, errors, directive);
133 }
134 }
135
136 fn enter_argument(
137 &mut self,
138 context: &mut OperationVisitorContext<'doc>,
139 errors: &mut ValidationErrorContext,
140 argument: &'doc (String, Value),
141 ) {
142 for visitor in &mut self.visitors {
143 visitor.enter_argument(context, errors, argument);
144 }
145 }
146
147 fn leave_argument(
148 &mut self,
149 context: &mut OperationVisitorContext<'doc>,
150 errors: &mut ValidationErrorContext,
151 argument: &(String, Value),
152 ) {
153 for visitor in &mut self.visitors {
154 visitor.leave_argument(context, errors, argument);
155 }
156 }
157
158 fn enter_selection_set(
159 &mut self,
160 context: &mut OperationVisitorContext<'doc>,
161 errors: &mut ValidationErrorContext,
162 selection_set: &'doc SelectionSet,
163 ) {
164 for visitor in &mut self.visitors {
165 visitor.enter_selection_set(context, errors, selection_set);
166 }
167 }
168
169 fn leave_selection_set(
170 &mut self,
171 context: &mut OperationVisitorContext<'doc>,
172 errors: &mut ValidationErrorContext,
173 selection_set: &SelectionSet,
174 ) {
175 for visitor in &mut self.visitors {
176 visitor.leave_selection_set(context, errors, selection_set);
177 }
178 }
179
180 fn enter_field(
181 &mut self,
182 context: &mut OperationVisitorContext<'doc>,
183 errors: &mut ValidationErrorContext,
184 field: &Field,
185 ) {
186 for visitor in &mut self.visitors {
187 visitor.enter_field(context, errors, field);
188 }
189 }
190
191 fn leave_field(
192 &mut self,
193 context: &mut OperationVisitorContext<'doc>,
194 errors: &mut ValidationErrorContext,
195 field: &Field,
196 ) {
197 for visitor in &mut self.visitors {
198 visitor.leave_field(context, errors, field);
199 }
200 }
201
202 fn enter_fragment_spread(
203 &mut self,
204 context: &mut OperationVisitorContext<'doc>,
205 errors: &mut ValidationErrorContext,
206 fragment_spread: &'doc FragmentSpread,
207 ) {
208 for visitor in &mut self.visitors {
209 visitor.enter_fragment_spread(context, errors, fragment_spread);
210 }
211 }
212
213 fn leave_fragment_spread(
214 &mut self,
215 context: &mut OperationVisitorContext<'doc>,
216 errors: &mut ValidationErrorContext,
217 fragment_spread: &FragmentSpread,
218 ) {
219 for visitor in &mut self.visitors {
220 visitor.leave_fragment_spread(context, errors, fragment_spread);
221 }
222 }
223
224 fn enter_inline_fragment(
225 &mut self,
226 context: &mut OperationVisitorContext<'doc>,
227 errors: &mut ValidationErrorContext,
228 inline_fragment: &InlineFragment,
229 ) {
230 for visitor in &mut self.visitors {
231 visitor.enter_inline_fragment(context, errors, inline_fragment);
232 }
233 }
234
235 fn leave_inline_fragment(
236 &mut self,
237 context: &mut OperationVisitorContext<'doc>,
238 errors: &mut ValidationErrorContext,
239 inline_fragment: &InlineFragment,
240 ) {
241 for visitor in &mut self.visitors {
242 visitor.leave_inline_fragment(context, errors, inline_fragment);
243 }
244 }
245
246 fn enter_null_value(
247 &mut self,
248 context: &mut OperationVisitorContext<'doc>,
249 errors: &mut ValidationErrorContext,
250 value: (),
251 ) {
252 for visitor in &mut self.visitors {
253 visitor.enter_null_value(context, errors, value);
254 }
255 }
256
257 fn leave_null_value(
258 &mut self,
259 context: &mut OperationVisitorContext<'doc>,
260 errors: &mut ValidationErrorContext,
261 value: (),
262 ) {
263 for visitor in &mut self.visitors {
264 visitor.leave_null_value(context, errors, value);
265 }
266 }
267
268 fn enter_scalar_value(
269 &mut self,
270 context: &mut OperationVisitorContext<'doc>,
271 errors: &mut ValidationErrorContext,
272 value: &Value,
273 ) {
274 for visitor in &mut self.visitors {
275 visitor.enter_scalar_value(context, errors, value);
276 }
277 }
278
279 fn leave_scalar_value(
280 &mut self,
281 context: &mut OperationVisitorContext<'doc>,
282 errors: &mut ValidationErrorContext,
283 value: &Value,
284 ) {
285 for visitor in &mut self.visitors {
286 visitor.leave_scalar_value(context, errors, value);
287 }
288 }
289
290 fn enter_enum_value(
291 &mut self,
292 context: &mut OperationVisitorContext<'doc>,
293 errors: &mut ValidationErrorContext,
294 value: &String,
295 ) {
296 for visitor in &mut self.visitors {
297 visitor.enter_enum_value(context, errors, value);
298 }
299 }
300
301 fn leave_enum_value(
302 &mut self,
303 context: &mut OperationVisitorContext<'doc>,
304 errors: &mut ValidationErrorContext,
305 value: &String,
306 ) {
307 for visitor in &mut self.visitors {
308 visitor.leave_enum_value(context, errors, value);
309 }
310 }
311
312 fn enter_variable_value(
313 &mut self,
314 context: &mut OperationVisitorContext<'doc>,
315 errors: &mut ValidationErrorContext,
316 variable_name: &'doc str,
317 ) {
318 for visitor in &mut self.visitors {
319 visitor.enter_variable_value(context, errors, variable_name);
320 }
321 }
322
323 fn leave_variable_value(
324 &mut self,
325 context: &mut OperationVisitorContext<'doc>,
326 errors: &mut ValidationErrorContext,
327 variable_name: &String,
328 ) {
329 for visitor in &mut self.visitors {
330 visitor.leave_variable_value(context, errors, variable_name);
331 }
332 }
333
334 fn enter_list_value(
335 &mut self,
336 context: &mut OperationVisitorContext<'doc>,
337 errors: &mut ValidationErrorContext,
338 values: &Vec<Value>,
339 ) {
340 for visitor in &mut self.visitors {
341 visitor.enter_list_value(context, errors, values);
342 }
343 }
344
345 fn leave_list_value(
346 &mut self,
347 context: &mut OperationVisitorContext<'doc>,
348 errors: &mut ValidationErrorContext,
349 values: &Vec<Value>,
350 ) {
351 for visitor in &mut self.visitors {
352 visitor.leave_list_value(context, errors, values);
353 }
354 }
355
356 fn enter_object_value(
357 &mut self,
358 context: &mut OperationVisitorContext<'doc>,
359 errors: &mut ValidationErrorContext,
360 fields: &[(String, Value)],
361 ) {
362 for visitor in &mut self.visitors {
363 visitor.enter_object_value(context, errors, fields);
364 }
365 }
366
367 fn leave_object_value(
368 &mut self,
369 context: &mut OperationVisitorContext<'doc>,
370 errors: &mut ValidationErrorContext,
371 fields: &[(String, Value)],
372 ) {
373 for visitor in &mut self.visitors {
374 visitor.leave_object_value(context, errors, fields);
375 }
376 }
377
378 fn enter_object_field(
379 &mut self,
380 context: &mut OperationVisitorContext<'doc>,
381 errors: &mut ValidationErrorContext,
382 field: &(String, Value),
383 ) {
384 for visitor in &mut self.visitors {
385 visitor.enter_object_field(context, errors, field);
386 }
387 }
388
389 fn leave_object_field(
390 &mut self,
391 context: &mut OperationVisitorContext<'doc>,
392 errors: &mut ValidationErrorContext,
393 field: &(String, Value),
394 ) {
395 for visitor in &mut self.visitors {
396 visitor.leave_object_field(context, errors, field);
397 }
398 }
399}
400
401pub trait ValidationRule: Send + Sync {
402 fn visitor<'doc>(&self) -> ValidationVisitor<'doc>;
403 fn error_code(&self) -> &'static str;
404}