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}