1use proc_macro2::Span;
4use syn::parse::Parse;
5
6use crate::{has, spanned::IntoSpan};
7
8use super::err;
9
10#[doc(inline)]
11pub use self::{dedup::Dedup, kind::Kind, validate::Validation};
12
13pub trait Attrs: Default + Parse {
15 fn try_merge(self, another: Self) -> syn::Result<Self>;
22
23 #[inline]
34 fn validate(&self, _: &str, _: Span) -> syn::Result<()> {
35 Ok(())
36 }
37
38 #[inline]
44 fn fallback(&mut self, _: &[syn::Attribute]) -> syn::Result<()> {
45 Ok(())
46 }
47
48 fn parse_attrs<T>(name: &str, item: &T) -> syn::Result<Self>
63 where
64 T: has::Attrs,
65 for<'a> &'a T: IntoSpan,
66 {
67 let attrs = item.attrs();
68 filter_by_name(name, attrs)
69 .map(syn::Attribute::parse_args)
70 .try_fold(Self::default(), |prev, curr| prev.try_merge(curr?))
71 .and_then(|mut parsed| {
72 parsed.fallback(attrs)?;
73 parsed.validate(name, item.into_span())?;
74 Ok(parsed)
75 })
76 }
77}
78
79impl<V: Attrs + Default + Parse> Attrs for Box<V> {
80 fn try_merge(self, another: Self) -> syn::Result<Self> {
81 (*self).try_merge(*another).map(Self::new)
82 }
83
84 fn validate(&self, attr_name: &str, item_span: Span) -> syn::Result<()> {
85 (**self).validate(attr_name, item_span)
86 }
87
88 fn fallback(&mut self, attrs: &[syn::Attribute]) -> syn::Result<()> {
89 (**self).fallback(attrs)
90 }
91
92 fn parse_attrs<T>(name: &str, item: &T) -> syn::Result<Self>
93 where
94 T: has::Attrs,
95 for<'a> &'a T: IntoSpan,
96 {
97 V::parse_attrs(name, item).map(Self::new)
98 }
99}
100
101pub fn filter_by_name<'n: 'ret, 'a: 'ret, 'ret>(
104 name: &'n str,
105 attrs: &'a [syn::Attribute],
106) -> impl Iterator<Item = &'a syn::Attribute> + 'ret {
107 attrs.iter().filter(move |attr| path_eq_single(attr.meta.path(), name))
108}
109
110#[must_use]
112fn path_eq_single(path: &syn::Path, value: &str) -> bool {
113 path.segments.len() == 1 && path.segments[0].ident == value
114}
115
116pub mod field {
117 use sealed::sealed;
122
123 use crate::field;
124
125 use super::{Dedup, Kind};
126
127 pub trait TryApply<V, K: Kind + ?Sized, D: Dedup + ?Sized>:
130 field::Container<V>
131 {
132 fn try_apply(&mut self, value: V) -> syn::Result<()>;
139 }
140
141 pub trait TryApplySelf<V, K: Kind + ?Sized, D: Dedup + ?Sized>:
145 TryApply<V, K, D>
146 {
147 fn try_apply_self(&mut self, another: Self) -> syn::Result<()>;
155 }
156
157 mod option {
158 use crate::{field::Container as _, spanned::IntoSpan};
161
162 use super::{
163 super::{dedup, err, kind, Dedup, Kind},
164 TryApply, TryApplySelf,
165 };
166
167 impl<V, K> TryApply<V, K, dedup::Unique> for Option<V>
168 where
169 for<'a> &'a V: IntoSpan,
170 K: Kind + kind::Single + ?Sized,
171 {
172 fn try_apply(&mut self, val: V) -> syn::Result<()> {
173 if self.has(&val) {
174 return Err(err::dup_attr_arg(&val));
175 }
176 self.set(val);
177 Ok(())
178 }
179 }
180
181 impl<V, K> TryApply<V, K, dedup::First> for Option<V>
182 where
183 K: Kind + kind::Single + ?Sized,
184 {
185 fn try_apply(&mut self, val: V) -> syn::Result<()> {
186 if !self.has(&val) {
187 self.set(val);
188 }
189 Ok(())
190 }
191 }
192
193 impl<V, K> TryApply<V, K, dedup::Last> for Option<V>
194 where
195 K: Kind + kind::Single + ?Sized,
196 {
197 fn try_apply(&mut self, val: V) -> syn::Result<()> {
198 self.set(val);
199 Ok(())
200 }
201 }
202
203 impl<V, K, D> TryApplySelf<V, K, D> for Option<V>
204 where
205 K: Kind + kind::Single + ?Sized,
206 D: Dedup + ?Sized,
207 Self: TryApply<V, K, D>,
208 {
209 fn try_apply_self(&mut self, another: Self) -> syn::Result<()> {
210 if let Some(val) = another {
211 self.try_apply(val)?;
212 }
213 Ok(())
214 }
215 }
216 }
217
218 mod required {
219 use crate::{field::Container as _, spanned::IntoSpan, Required};
222
223 use super::{
224 super::{dedup, err, kind, Dedup, Kind},
225 TryApply, TryApplySelf,
226 };
227
228 impl<V, K> TryApply<V, K, dedup::Unique> for Required<V>
229 where
230 for<'a> &'a V: IntoSpan,
231 K: Kind + kind::Single + ?Sized,
232 {
233 fn try_apply(&mut self, val: V) -> syn::Result<()> {
234 if self.has(&val) {
235 return Err(err::dup_attr_arg(&val));
236 }
237 self.set(val);
238 Ok(())
239 }
240 }
241
242 impl<V, K> TryApply<V, K, dedup::First> for Required<V>
243 where
244 K: Kind + kind::Single + ?Sized,
245 {
246 fn try_apply(&mut self, val: V) -> syn::Result<()> {
247 if !self.has(&val) {
248 self.set(val);
249 }
250 Ok(())
251 }
252 }
253
254 impl<V, K> TryApply<V, K, dedup::Last> for Required<V>
255 where
256 K: Kind + kind::Single + ?Sized,
257 {
258 fn try_apply(&mut self, val: V) -> syn::Result<()> {
259 self.set(val);
260 Ok(())
261 }
262 }
263
264 impl<V, K, D> TryApplySelf<V, K, D> for Required<V>
265 where
266 K: Kind + kind::Single + ?Sized,
267 D: Dedup + ?Sized,
268 Self: TryApply<V, K, D>,
269 {
270 fn try_apply_self(&mut self, mut another: Self) -> syn::Result<()> {
271 if let Some(val) = another.take() {
272 self.try_apply(val)?;
273 }
274 Ok(())
275 }
276 }
277 }
278
279 mod vec {
280 use crate::{field::Container as _, spanned::IntoSpan};
283
284 use super::{
285 super::{dedup, err, kind, Dedup},
286 TryApply, TryApplySelf,
287 };
288
289 impl<V> TryApply<V, kind::Nested, dedup::Unique> for Vec<V>
290 where
291 for<'a> &'a V: IntoSpan,
292 V: PartialEq,
293 {
294 fn try_apply(&mut self, val: V) -> syn::Result<()> {
295 if self.has(&val) {
296 return Err(err::dup_attr_arg(&val));
297 }
298 self.set(val);
299 Ok(())
300 }
301 }
302
303 impl<V: PartialEq> TryApply<V, kind::Nested, dedup::First> for Vec<V> {
304 fn try_apply(&mut self, val: V) -> syn::Result<()> {
305 if !self.has(&val) {
306 self.set(val);
307 }
308 Ok(())
309 }
310 }
311
312 impl<V: PartialEq> TryApply<V, kind::Nested, dedup::Last> for Vec<V> {
313 fn try_apply(&mut self, val: V) -> syn::Result<()> {
314 self.set(val);
315 Ok(())
316 }
317 }
318
319 impl<V, D> TryApplySelf<V, kind::Nested, D> for Vec<V>
320 where
321 D: Dedup + ?Sized,
322 Self: TryApply<V, kind::Nested, D>,
323 {
324 fn try_apply_self(&mut self, another: Self) -> syn::Result<()> {
325 for val in another {
326 self.try_apply(val)?;
327 }
328 Ok(())
329 }
330 }
331
332 impl<V> TryApply<V, kind::Value, dedup::Unique> for Vec<V>
333 where
334 for<'a> &'a V: IntoSpan,
335 V: PartialEq,
336 {
337 fn try_apply(&mut self, val: V) -> syn::Result<()> {
338 if self.has(&val) {
339 return Err(err::dup_attr_arg(&val));
340 }
341 self.set(val);
342 Ok(())
343 }
344 }
345
346 impl<V: PartialEq> TryApply<V, kind::Value, dedup::First> for Vec<V> {
347 fn try_apply(&mut self, val: V) -> syn::Result<()> {
348 if !self.has(&val) {
349 self.set(val);
350 }
351 Ok(())
352 }
353 }
354
355 impl<V: PartialEq> TryApply<V, kind::Value, dedup::Last> for Vec<V> {
356 fn try_apply(&mut self, val: V) -> syn::Result<()> {
357 self.set(val);
358 Ok(())
359 }
360 }
361
362 impl<V, D> TryApplySelf<V, kind::Value, D> for Vec<V>
363 where
364 D: Dedup + ?Sized,
365 Self: TryApply<V, kind::Value, D>,
366 {
367 fn try_apply_self(&mut self, another: Self) -> syn::Result<()> {
368 for val in another {
369 self.try_apply(val)?;
370 }
371 Ok(())
372 }
373 }
374 }
375
376 mod hashset {
377 use std::{
380 collections::HashSet,
381 hash::{BuildHasher, Hash},
382 };
383
384 use crate::{field::Container as _, spanned::IntoSpan};
385
386 use super::{
387 super::{dedup, err, kind, Dedup},
388 TryApply, TryApplySelf,
389 };
390
391 impl<V, S> TryApply<V, kind::Nested, dedup::Unique> for HashSet<V, S>
392 where
393 for<'a> &'a V: IntoSpan,
394 V: Eq + Hash,
395 S: BuildHasher,
396 {
397 fn try_apply(&mut self, val: V) -> syn::Result<()> {
398 if self.has(&val) {
399 return Err(err::dup_attr_arg(&val));
400 }
401 self.set(val);
402 Ok(())
403 }
404 }
405
406 impl<V, S> TryApply<V, kind::Nested, dedup::First> for HashSet<V, S>
407 where
408 V: Eq + Hash,
409 S: BuildHasher,
410 {
411 fn try_apply(&mut self, val: V) -> syn::Result<()> {
412 if !self.has(&val) {
413 self.set(val);
414 }
415 Ok(())
416 }
417 }
418
419 impl<V, S> TryApply<V, kind::Nested, dedup::Last> for HashSet<V, S>
420 where
421 V: Eq + Hash,
422 S: BuildHasher,
423 {
424 fn try_apply(&mut self, val: V) -> syn::Result<()> {
425 self.set(val);
426 Ok(())
427 }
428 }
429
430 impl<V, S, D> TryApplySelf<V, kind::Nested, D> for HashSet<V, S>
431 where
432 D: Dedup + ?Sized,
433 S: BuildHasher,
434 Self: TryApply<V, kind::Nested, D>,
435 {
436 fn try_apply_self(&mut self, another: Self) -> syn::Result<()> {
437 for val in another {
438 self.try_apply(val)?;
439 }
440 Ok(())
441 }
442 }
443
444 impl<V, S> TryApply<V, kind::Value, dedup::Unique> for HashSet<V, S>
445 where
446 for<'a> &'a V: IntoSpan,
447 V: Eq + Hash,
448 S: BuildHasher,
449 {
450 fn try_apply(&mut self, val: V) -> syn::Result<()> {
451 if self.has(&val) {
452 return Err(err::dup_attr_arg(&val));
453 }
454 self.set(val);
455 Ok(())
456 }
457 }
458
459 impl<V, S> TryApply<V, kind::Value, dedup::First> for HashSet<V, S>
460 where
461 V: Eq + Hash,
462 S: BuildHasher,
463 {
464 fn try_apply(&mut self, val: V) -> syn::Result<()> {
465 if !self.has(&val) {
466 self.set(val);
467 }
468 Ok(())
469 }
470 }
471
472 impl<V, S> TryApply<V, kind::Value, dedup::Last> for HashSet<V, S>
473 where
474 V: Eq + Hash,
475 S: BuildHasher,
476 {
477 fn try_apply(&mut self, val: V) -> syn::Result<()> {
478 self.set(val);
479 Ok(())
480 }
481 }
482
483 impl<V, S, D> TryApplySelf<V, kind::Value, D> for HashSet<V, S>
484 where
485 D: Dedup + ?Sized,
486 S: BuildHasher,
487 Self: TryApply<V, kind::Value, D>,
488 {
489 fn try_apply_self(&mut self, another: Self) -> syn::Result<()> {
490 for val in another {
491 self.try_apply(val)?;
492 }
493 Ok(())
494 }
495 }
496 }
497
498 mod btreeset {
499 use std::collections::BTreeSet;
502
503 use crate::{field::Container as _, spanned::IntoSpan};
504
505 use super::{
506 super::{dedup, err, kind, Dedup},
507 TryApply, TryApplySelf,
508 };
509
510 impl<V> TryApply<V, kind::Nested, dedup::Unique> for BTreeSet<V>
511 where
512 for<'a> &'a V: IntoSpan,
513 V: Ord,
514 {
515 fn try_apply(&mut self, val: V) -> syn::Result<()> {
516 if self.has(&val) {
517 return Err(err::dup_attr_arg(&val));
518 }
519 self.set(val);
520 Ok(())
521 }
522 }
523
524 impl<V: Ord> TryApply<V, kind::Nested, dedup::First> for BTreeSet<V> {
525 fn try_apply(&mut self, val: V) -> syn::Result<()> {
526 if !self.has(&val) {
527 self.set(val);
528 }
529 Ok(())
530 }
531 }
532
533 impl<V: Ord> TryApply<V, kind::Nested, dedup::Last> for BTreeSet<V> {
534 fn try_apply(&mut self, val: V) -> syn::Result<()> {
535 self.set(val);
536 Ok(())
537 }
538 }
539
540 impl<V, D> TryApplySelf<V, kind::Nested, D> for BTreeSet<V>
541 where
542 D: Dedup + ?Sized,
543 Self: TryApply<V, kind::Nested, D>,
544 {
545 fn try_apply_self(&mut self, another: Self) -> syn::Result<()> {
546 for val in another {
547 self.try_apply(val)?;
548 }
549 Ok(())
550 }
551 }
552
553 impl<V> TryApply<V, kind::Value, dedup::Unique> for BTreeSet<V>
554 where
555 for<'a> &'a V: IntoSpan,
556 V: Ord,
557 {
558 fn try_apply(&mut self, val: V) -> syn::Result<()> {
559 if self.has(&val) {
560 return Err(err::dup_attr_arg(&val));
561 }
562 self.set(val);
563 Ok(())
564 }
565 }
566
567 impl<V: Ord> TryApply<V, kind::Value, dedup::First> for BTreeSet<V> {
568 fn try_apply(&mut self, val: V) -> syn::Result<()> {
569 if !self.has(&val) {
570 self.set(val);
571 }
572 Ok(())
573 }
574 }
575
576 impl<V: Ord> TryApply<V, kind::Value, dedup::Last> for BTreeSet<V> {
577 fn try_apply(&mut self, val: V) -> syn::Result<()> {
578 self.set(val);
579 Ok(())
580 }
581 }
582
583 impl<V, D> TryApplySelf<V, kind::Value, D> for BTreeSet<V>
584 where
585 D: Dedup + ?Sized,
586 Self: TryApply<V, kind::Value, D>,
587 {
588 fn try_apply_self(&mut self, another: Self) -> syn::Result<()> {
589 for val in another {
590 self.try_apply(val)?;
591 }
592 Ok(())
593 }
594 }
595 }
596
597 mod hashmap {
598 use std::{
601 collections::HashMap,
602 hash::{BuildHasher, Hash},
603 };
604
605 use crate::{field::Container as _, spanned::IntoSpan};
606
607 use super::{
608 super::{dedup, err, kind, Dedup},
609 TryApply, TryApplySelf,
610 };
611
612 impl<K, V, S: BuildHasher> TryApply<(K, V), kind::Map, dedup::Unique>
613 for HashMap<K, V, S>
614 where
615 for<'a> &'a K: IntoSpan,
616 K: Eq + Hash,
617 {
618 fn try_apply(&mut self, val: (K, V)) -> syn::Result<()> {
619 if self.has(&val) {
620 return Err(err::dup_attr_arg(&val.0));
621 }
622 self.set(val);
623 Ok(())
624 }
625 }
626
627 impl<K: Eq + Hash, V, S: BuildHasher>
628 TryApply<(K, V), kind::Map, dedup::First> for HashMap<K, V, S>
629 {
630 fn try_apply(&mut self, val: (K, V)) -> syn::Result<()> {
631 if !self.has(&val) {
632 self.set(val);
633 }
634 Ok(())
635 }
636 }
637
638 impl<K: Eq + Hash, V, S: BuildHasher>
639 TryApply<(K, V), kind::Map, dedup::Last> for HashMap<K, V, S>
640 {
641 fn try_apply(&mut self, val: (K, V)) -> syn::Result<()> {
642 self.set(val);
643 Ok(())
644 }
645 }
646
647 impl<K, V, D, S> TryApplySelf<(K, V), kind::Map, D> for HashMap<K, V, S>
648 where
649 D: Dedup + ?Sized,
650 S: BuildHasher,
651 Self: TryApply<(K, V), kind::Map, D>,
652 {
653 fn try_apply_self(&mut self, another: Self) -> syn::Result<()> {
654 for val in another {
655 self.try_apply(val)?;
656 }
657 Ok(())
658 }
659 }
660 }
661
662 mod btreemap {
663 use std::collections::BTreeMap;
666
667 use crate::{field::Container as _, spanned::IntoSpan};
668
669 use super::{
670 super::{dedup, err, kind, Dedup},
671 TryApply, TryApplySelf,
672 };
673
674 impl<K, V> TryApply<(K, V), kind::Map, dedup::Unique> for BTreeMap<K, V>
675 where
676 for<'a> &'a K: IntoSpan,
677 K: Ord,
678 {
679 fn try_apply(&mut self, val: (K, V)) -> syn::Result<()> {
680 if self.has(&val) {
681 return Err(err::dup_attr_arg(&val.0));
682 }
683 self.set(val);
684 Ok(())
685 }
686 }
687
688 impl<K, V> TryApply<(K, V), kind::Map, dedup::First> for BTreeMap<K, V>
689 where
690 K: Ord,
691 {
692 fn try_apply(&mut self, val: (K, V)) -> syn::Result<()> {
693 if !self.has(&val) {
694 self.set(val);
695 }
696 Ok(())
697 }
698 }
699
700 impl<K, V> TryApply<(K, V), kind::Map, dedup::Last> for BTreeMap<K, V>
701 where
702 K: Ord,
703 {
704 fn try_apply(&mut self, val: (K, V)) -> syn::Result<()> {
705 self.set(val);
706 Ok(())
707 }
708 }
709
710 impl<K, V, D> TryApplySelf<(K, V), kind::Map, D> for BTreeMap<K, V>
711 where
712 D: Dedup + ?Sized,
713 Self: TryApply<(K, V), kind::Map, D>,
714 {
715 fn try_apply_self(&mut self, another: Self) -> syn::Result<()> {
716 for val in another {
717 self.try_apply(val)?;
718 }
719 Ok(())
720 }
721 }
722 }
723
724 #[sealed]
728 pub trait TryMerge<V> {
729 fn try_merge<K, D>(&mut self, value: V) -> syn::Result<()>
737 where
738 Self: TryApply<V, K, D>,
739 K: Kind + ?Sized,
740 D: Dedup + ?Sized;
741
742 fn try_merge_self<K, D>(&mut self, another: Self) -> syn::Result<()>
751 where
752 Self: TryApplySelf<V, K, D> + Sized,
753 K: Kind + ?Sized,
754 D: Dedup + ?Sized;
755 }
756
757 #[sealed]
758 impl<T: ?Sized, V> TryMerge<V> for T {
759 fn try_merge<K, D>(&mut self, val: V) -> syn::Result<()>
760 where
761 Self: TryApply<V, K, D>,
762 K: Kind + ?Sized,
763 D: Dedup + ?Sized,
764 {
765 <Self as TryApply<V, K, D>>::try_apply(self, val)
766 }
767
768 fn try_merge_self<K, D>(&mut self, another: Self) -> syn::Result<()>
769 where
770 Self: TryApplySelf<V, K, D> + Sized,
771 K: Kind + ?Sized,
772 D: Dedup + ?Sized,
773 {
774 <Self as TryApplySelf<V, K, D>>::try_apply_self(self, another)
775 }
776 }
777}
778
779pub mod kind {
780 use sealed::sealed;
785
786 #[sealed]
792 pub trait Kind {}
793
794 #[sealed]
798 pub trait Single {}
799
800 #[derive(Clone, Copy, Debug)]
810 pub enum Ident {}
811
812 #[sealed]
813 impl Kind for Ident {}
814
815 #[sealed]
816 impl Single for Ident {}
817
818 #[derive(Clone, Copy, Debug)]
826 pub enum Nested {}
827
828 #[sealed]
829 impl Kind for Nested {}
830
831 #[sealed]
832 impl Single for Nested {}
833
834 #[derive(Clone, Copy, Debug)]
846 pub enum Value {}
847
848 #[sealed]
849 impl Kind for Value {}
850
851 #[sealed]
852 impl Single for Value {}
853
854 #[derive(Clone, Copy, Debug)]
864 pub enum Map {}
865
866 #[sealed]
867 impl Kind for Map {}
868}
869
870pub mod dedup {
871 use sealed::sealed;
876
877 #[sealed]
883 pub trait Dedup {}
884
885 #[derive(Clone, Copy, Debug)]
890 pub enum Unique {}
891
892 #[sealed]
893 impl Dedup for Unique {}
894
895 #[derive(Clone, Copy, Debug)]
900 pub enum First {}
901
902 #[sealed]
903 impl Dedup for First {}
904
905 #[derive(Clone, Copy, Debug)]
910 pub enum Last {}
911
912 #[sealed]
913 impl Dedup for Last {}
914}
915
916pub mod validate {
917 use sealed::sealed;
922
923 #[doc(inline)]
924 pub use self::rule::Rule;
925
926 pub trait Validation<R: Rule + ?Sized> {
932 fn validation(&self) -> syn::Result<()>;
938 }
939
940 mod option {
941 use super::{rule, Validation};
944
945 impl<V> Validation<rule::Provided> for Option<V> {
946 fn validation(&self) -> syn::Result<()> {
947 Ok(())
948 }
949 }
950 }
951
952 mod required {
953 use proc_macro2::Span;
956
957 use crate::Required;
958
959 use super::{rule, Validation};
960
961 impl<V> Validation<rule::Provided> for Required<V> {
962 fn validation(&self) -> syn::Result<()> {
963 self.is_present().then_some(()).ok_or_else(|| {
964 syn::Error::new(
965 Span::call_site(),
966 "is expected to be present, but is absent",
967 )
968 })
969 }
970 }
971 }
972
973 mod vec {
974 use super::{rule, Validation};
977
978 impl<V> Validation<rule::Provided> for Vec<V> {
979 fn validation(&self) -> syn::Result<()> {
980 Ok(())
981 }
982 }
983 }
984
985 mod hashset {
986 use std::{
989 collections::HashSet,
990 hash::{BuildHasher, Hash},
991 };
992
993 use super::{rule, Validation};
994
995 impl<V, S> Validation<rule::Provided> for HashSet<V, S>
996 where
997 V: Eq + Hash,
998 S: BuildHasher,
999 {
1000 fn validation(&self) -> syn::Result<()> {
1001 Ok(())
1002 }
1003 }
1004 }
1005
1006 mod btreeset {
1007 use std::collections::BTreeSet;
1010
1011 use super::{rule, Validation};
1012
1013 impl<V: Ord> Validation<rule::Provided> for BTreeSet<V> {
1014 fn validation(&self) -> syn::Result<()> {
1015 Ok(())
1016 }
1017 }
1018 }
1019
1020 mod hashmap {
1021 use std::{
1024 collections::HashMap,
1025 hash::{BuildHasher, Hash},
1026 };
1027
1028 use super::{rule, Validation};
1029
1030 impl<K, V, S> Validation<rule::Provided> for HashMap<K, V, S>
1031 where
1032 K: Eq + Hash,
1033 S: BuildHasher,
1034 {
1035 fn validation(&self) -> syn::Result<()> {
1036 Ok(())
1037 }
1038 }
1039 }
1040
1041 mod btreemap {
1042 use std::collections::BTreeMap;
1045
1046 use super::{rule, Validation};
1047
1048 impl<K: Ord, V> Validation<rule::Provided> for BTreeMap<K, V> {
1049 fn validation(&self) -> syn::Result<()> {
1050 Ok(())
1051 }
1052 }
1053 }
1054
1055 #[sealed]
1058 pub trait Validate {
1059 fn validate<R: Rule + ?Sized>(&self) -> syn::Result<()>
1065 where
1066 Self: Validation<R>;
1067 }
1068
1069 #[sealed]
1070 impl<T: ?Sized> Validate for T {
1071 fn validate<R: Rule + ?Sized>(&self) -> syn::Result<()>
1072 where
1073 Self: Validation<R>,
1074 {
1075 self.validation()
1076 }
1077 }
1078
1079 pub mod rule {
1080 use sealed::sealed;
1085
1086 #[sealed]
1090 pub trait Rule {}
1091
1092 #[derive(Clone, Copy, Debug)]
1097 pub enum Provided {}
1098
1099 #[sealed]
1100 impl Rule for Provided {}
1101 }
1102}