Skip to main content

graphql_tools/validation/rules/
rule.rs

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}