proto_types/protovalidate/
rule_matching.rs

1use proc_macro2::Span;
2use syn::Error;
3
4use crate::{
5  protovalidate::{
6    field_rules::Type as RulesType, AnyRules, BoolRules, BytesRules, DoubleRules, DurationRules,
7    EnumRules, Fixed32Rules, Fixed64Rules, FloatRules, Int32Rules, Int64Rules, SFixed32Rules,
8    SFixed64Rules, SInt32Rules, SInt64Rules, StringRules, TimestampRules, UInt32Rules, UInt64Rules,
9  },
10  FieldType,
11};
12
13impl RulesType {
14  pub fn matches_type(
15    &self,
16    field_type: FieldType,
17    field_span: Span,
18    error_prefix: &str,
19  ) -> Result<(), Error> {
20    match self {
21      RulesType::Float(v) => v.matches_type(field_type, field_span, error_prefix),
22      RulesType::Double(v) => v.matches_type(field_type, field_span, error_prefix),
23      RulesType::Int32(v) => v.matches_type(field_type, field_span, error_prefix),
24      RulesType::Int64(v) => v.matches_type(field_type, field_span, error_prefix),
25      RulesType::Uint32(v) => v.matches_type(field_type, field_span, error_prefix),
26      RulesType::Uint64(v) => v.matches_type(field_type, field_span, error_prefix),
27      RulesType::Sint32(v) => v.matches_type(field_type, field_span, error_prefix),
28      RulesType::Sint64(v) => v.matches_type(field_type, field_span, error_prefix),
29      RulesType::Fixed32(v) => v.matches_type(field_type, field_span, error_prefix),
30      RulesType::Fixed64(v) => v.matches_type(field_type, field_span, error_prefix),
31      RulesType::Sfixed32(v) => v.matches_type(field_type, field_span, error_prefix),
32      RulesType::Sfixed64(v) => v.matches_type(field_type, field_span, error_prefix),
33      RulesType::Bool(v) => v.matches_type(field_type, field_span, error_prefix),
34      RulesType::String(v) => v.matches_type(field_type, field_span, error_prefix),
35      RulesType::Bytes(v) => v.matches_type(field_type, field_span, error_prefix),
36      RulesType::Enum(v) => v.matches_type(field_type, field_span, error_prefix),
37      RulesType::Repeated(_) => Ok(()),
38      RulesType::Map(_) => Ok(()),
39      RulesType::Any(_) => Ok(()),
40      RulesType::Duration(_) => Ok(()),
41      RulesType::Timestamp(_) => Ok(()),
42    }
43  }
44}
45
46pub trait RuleMatches {
47  const RULE_TYPE: FieldType;
48  fn matches_type(
49    &self,
50    field_type: FieldType,
51    field_span: Span,
52    error_prefix: &str,
53  ) -> Result<(), Error>;
54}
55
56fn get_wrong_rule_error(
57  field_span: Span,
58  error_prefix: &str,
59  expected: FieldType,
60  actual: FieldType,
61) -> Error {
62  Error::new(
63    field_span,
64    format!(
65      "{} wrong rule type. Expected {:#?}, got {:#?}",
66      error_prefix, expected, actual
67    ),
68  )
69}
70
71impl RuleMatches for DurationRules {
72  const RULE_TYPE: FieldType = FieldType::Duration;
73  fn matches_type(
74    &self,
75    field_type: FieldType,
76    field_span: Span,
77    error_prefix: &str,
78  ) -> Result<(), Error> {
79    if !matches!(field_type, Self::RULE_TYPE) {
80      Err(get_wrong_rule_error(
81        field_span,
82        error_prefix,
83        Self::RULE_TYPE,
84        field_type,
85      ))
86    } else {
87      Ok(())
88    }
89  }
90}
91
92impl RuleMatches for TimestampRules {
93  const RULE_TYPE: FieldType = FieldType::Timestamp;
94  fn matches_type(
95    &self,
96    field_type: FieldType,
97    field_span: Span,
98    error_prefix: &str,
99  ) -> Result<(), Error> {
100    if !matches!(field_type, Self::RULE_TYPE) {
101      Err(get_wrong_rule_error(
102        field_span,
103        error_prefix,
104        Self::RULE_TYPE,
105        field_type,
106      ))
107    } else {
108      Ok(())
109    }
110  }
111}
112
113impl RuleMatches for AnyRules {
114  const RULE_TYPE: FieldType = FieldType::Any;
115  fn matches_type(
116    &self,
117    field_type: FieldType,
118    field_span: Span,
119    error_prefix: &str,
120  ) -> Result<(), Error> {
121    if !matches!(field_type, Self::RULE_TYPE) {
122      Err(get_wrong_rule_error(
123        field_span,
124        error_prefix,
125        Self::RULE_TYPE,
126        field_type,
127      ))
128    } else {
129      Ok(())
130    }
131  }
132}
133
134impl RuleMatches for FloatRules {
135  const RULE_TYPE: FieldType = FieldType::Float;
136  fn matches_type(
137    &self,
138    field_type: FieldType,
139    field_span: Span,
140    error_prefix: &str,
141  ) -> Result<(), Error> {
142    if !matches!(field_type, Self::RULE_TYPE) {
143      Err(get_wrong_rule_error(
144        field_span,
145        error_prefix,
146        Self::RULE_TYPE,
147        field_type,
148      ))
149    } else {
150      Ok(())
151    }
152  }
153}
154
155impl RuleMatches for DoubleRules {
156  const RULE_TYPE: FieldType = FieldType::Double;
157  fn matches_type(
158    &self,
159    field_type: FieldType,
160    field_span: Span,
161    error_prefix: &str,
162  ) -> Result<(), Error> {
163    if !matches!(field_type, Self::RULE_TYPE) {
164      Err(get_wrong_rule_error(
165        field_span,
166        error_prefix,
167        Self::RULE_TYPE,
168        field_type,
169      ))
170    } else {
171      Ok(())
172    }
173  }
174}
175
176impl RuleMatches for Int32Rules {
177  const RULE_TYPE: FieldType = FieldType::Int32;
178  fn matches_type(
179    &self,
180    field_type: FieldType,
181    field_span: Span,
182    error_prefix: &str,
183  ) -> Result<(), Error> {
184    if !matches!(field_type, Self::RULE_TYPE) {
185      Err(get_wrong_rule_error(
186        field_span,
187        error_prefix,
188        Self::RULE_TYPE,
189        field_type,
190      ))
191    } else {
192      Ok(())
193    }
194  }
195}
196
197impl RuleMatches for Int64Rules {
198  const RULE_TYPE: FieldType = FieldType::Int64;
199  fn matches_type(
200    &self,
201    field_type: FieldType,
202    field_span: Span,
203    error_prefix: &str,
204  ) -> Result<(), Error> {
205    if !matches!(field_type, Self::RULE_TYPE) {
206      Err(get_wrong_rule_error(
207        field_span,
208        error_prefix,
209        Self::RULE_TYPE,
210        field_type,
211      ))
212    } else {
213      Ok(())
214    }
215  }
216}
217
218impl RuleMatches for UInt32Rules {
219  const RULE_TYPE: FieldType = FieldType::Uint32;
220  fn matches_type(
221    &self,
222    field_type: FieldType,
223    field_span: Span,
224    error_prefix: &str,
225  ) -> Result<(), Error> {
226    if !matches!(field_type, Self::RULE_TYPE) {
227      Err(get_wrong_rule_error(
228        field_span,
229        error_prefix,
230        Self::RULE_TYPE,
231        field_type,
232      ))
233    } else {
234      Ok(())
235    }
236  }
237}
238
239impl RuleMatches for UInt64Rules {
240  const RULE_TYPE: FieldType = FieldType::Uint64;
241  fn matches_type(
242    &self,
243    field_type: FieldType,
244    field_span: Span,
245    error_prefix: &str,
246  ) -> Result<(), Error> {
247    if !matches!(field_type, Self::RULE_TYPE) {
248      Err(get_wrong_rule_error(
249        field_span,
250        error_prefix,
251        Self::RULE_TYPE,
252        field_type,
253      ))
254    } else {
255      Ok(())
256    }
257  }
258}
259
260impl RuleMatches for SInt32Rules {
261  const RULE_TYPE: FieldType = FieldType::Sint32;
262  fn matches_type(
263    &self,
264    field_type: FieldType,
265    field_span: Span,
266    error_prefix: &str,
267  ) -> Result<(), Error> {
268    if !matches!(field_type, Self::RULE_TYPE) {
269      Err(get_wrong_rule_error(
270        field_span,
271        error_prefix,
272        Self::RULE_TYPE,
273        field_type,
274      ))
275    } else {
276      Ok(())
277    }
278  }
279}
280
281impl RuleMatches for SInt64Rules {
282  const RULE_TYPE: FieldType = FieldType::Sint64;
283  fn matches_type(
284    &self,
285    field_type: FieldType,
286    field_span: Span,
287    error_prefix: &str,
288  ) -> Result<(), Error> {
289    if !matches!(field_type, Self::RULE_TYPE) {
290      Err(get_wrong_rule_error(
291        field_span,
292        error_prefix,
293        Self::RULE_TYPE,
294        field_type,
295      ))
296    } else {
297      Ok(())
298    }
299  }
300}
301
302impl RuleMatches for Fixed32Rules {
303  const RULE_TYPE: FieldType = FieldType::Fixed32;
304  fn matches_type(
305    &self,
306    field_type: FieldType,
307    field_span: Span,
308    error_prefix: &str,
309  ) -> Result<(), Error> {
310    if !matches!(field_type, Self::RULE_TYPE) {
311      Err(get_wrong_rule_error(
312        field_span,
313        error_prefix,
314        Self::RULE_TYPE,
315        field_type,
316      ))
317    } else {
318      Ok(())
319    }
320  }
321}
322
323impl RuleMatches for Fixed64Rules {
324  const RULE_TYPE: FieldType = FieldType::Fixed64;
325  fn matches_type(
326    &self,
327    field_type: FieldType,
328    field_span: Span,
329    error_prefix: &str,
330  ) -> Result<(), Error> {
331    if !matches!(field_type, Self::RULE_TYPE) {
332      Err(get_wrong_rule_error(
333        field_span,
334        error_prefix,
335        Self::RULE_TYPE,
336        field_type,
337      ))
338    } else {
339      Ok(())
340    }
341  }
342}
343
344impl RuleMatches for SFixed32Rules {
345  const RULE_TYPE: FieldType = FieldType::Sfixed32;
346  fn matches_type(
347    &self,
348    field_type: FieldType,
349    field_span: Span,
350    error_prefix: &str,
351  ) -> Result<(), Error> {
352    if !matches!(field_type, Self::RULE_TYPE) {
353      Err(get_wrong_rule_error(
354        field_span,
355        error_prefix,
356        Self::RULE_TYPE,
357        field_type,
358      ))
359    } else {
360      Ok(())
361    }
362  }
363}
364
365impl RuleMatches for SFixed64Rules {
366  const RULE_TYPE: FieldType = FieldType::Sfixed64;
367  fn matches_type(
368    &self,
369    field_type: FieldType,
370    field_span: Span,
371    error_prefix: &str,
372  ) -> Result<(), Error> {
373    if !matches!(field_type, Self::RULE_TYPE) {
374      Err(get_wrong_rule_error(
375        field_span,
376        error_prefix,
377        Self::RULE_TYPE,
378        field_type,
379      ))
380    } else {
381      Ok(())
382    }
383  }
384}
385
386impl RuleMatches for BoolRules {
387  const RULE_TYPE: FieldType = FieldType::Bool;
388  fn matches_type(
389    &self,
390    field_type: FieldType,
391    field_span: Span,
392    error_prefix: &str,
393  ) -> Result<(), Error> {
394    if !matches!(field_type, Self::RULE_TYPE) {
395      Err(get_wrong_rule_error(
396        field_span,
397        error_prefix,
398        Self::RULE_TYPE,
399        field_type,
400      ))
401    } else {
402      Ok(())
403    }
404  }
405}
406
407impl RuleMatches for EnumRules {
408  const RULE_TYPE: FieldType = FieldType::Enum;
409  fn matches_type(
410    &self,
411    field_type: FieldType,
412    field_span: Span,
413    error_prefix: &str,
414  ) -> Result<(), Error> {
415    if !matches!(field_type, Self::RULE_TYPE) {
416      Err(get_wrong_rule_error(
417        field_span,
418        error_prefix,
419        Self::RULE_TYPE,
420        field_type,
421      ))
422    } else {
423      Ok(())
424    }
425  }
426}
427
428impl RuleMatches for StringRules {
429  const RULE_TYPE: FieldType = FieldType::String;
430  fn matches_type(
431    &self,
432    field_type: FieldType,
433    field_span: Span,
434    error_prefix: &str,
435  ) -> Result<(), Error> {
436    if !matches!(field_type, Self::RULE_TYPE) {
437      Err(get_wrong_rule_error(
438        field_span,
439        error_prefix,
440        Self::RULE_TYPE,
441        field_type,
442      ))
443    } else {
444      Ok(())
445    }
446  }
447}
448
449impl RuleMatches for BytesRules {
450  const RULE_TYPE: FieldType = FieldType::Bytes;
451  fn matches_type(
452    &self,
453    field_type: FieldType,
454    field_span: Span,
455    error_prefix: &str,
456  ) -> Result<(), Error> {
457    if !matches!(field_type, Self::RULE_TYPE) {
458      Err(get_wrong_rule_error(
459        field_span,
460        error_prefix,
461        Self::RULE_TYPE,
462        field_type,
463      ))
464    } else {
465      Ok(())
466    }
467  }
468}