synthez_core/parse/
attrs.rs

1//! Machinery for parsing [`syn::Attribute`]s into a custom defined struct.
2
3use 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
13/// [`Parse`]ing of [`syn::Attribute`]s into a custom defined struct.
14pub trait Attrs: Default + Parse {
15    /// Tries to merge two sets of parsed attributes into a single one,
16    /// reporting about duplicates, if any.
17    ///
18    /// # Errors
19    ///
20    /// If merging cannot be performed.
21    fn try_merge(self, another: Self) -> syn::Result<Self>;
22
23    /// Validates these parsed attributes to meet additional invariants, if
24    /// required.
25    ///
26    /// The provided string contains name of the parsed [`syn::Attribute`], and
27    /// the provided [`Span`] refers to the item this [`syn::Attribute`] is
28    /// applied to. Use them to make reported errors well descriptive.
29    ///
30    /// # Errors
31    ///
32    /// If validation fails.
33    #[inline]
34    fn validate(&self, _: &str, _: Span) -> syn::Result<()> {
35        Ok(())
36    }
37
38    /// Falls back to another values from [`syn::Attribute`]s, if required.
39    ///
40    /// # Errors
41    ///
42    /// If retrieving fallback values fails.
43    #[inline]
44    fn fallback(&mut self, _: &[syn::Attribute]) -> syn::Result<()> {
45        Ok(())
46    }
47
48    /// Parses this structure from the [`syn::Attribute`]s with the given `name`
49    /// and contained in the given `item`.
50    ///
51    /// If multiple [`syn::Attribute`]s occur with the same `name` then they all
52    /// are parsed separately and then [`Attrs::try_merge`]d.
53    ///
54    /// If none [`syn::Attribute`]s occur with the given `name` then [`Default`]
55    /// value is returned, modulo [`Attrs::validate`].
56    ///
57    /// # Errors
58    ///
59    /// - If [`Parse`]ing of this [`Attrs`] fails.
60    /// - If either [`Attrs::try_merge()`], [`Attrs::validate()`] or
61    ///   [`Attrs::fallback()`] fails.
62    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
101/// Filters the given `attrs` to contain [`syn::Attribute`]s only with the given
102/// `name`.
103pub 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/// Compares the given `path` with the one-segment string `value` to be equal.
111#[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    //! Batteries for working with [`Attrs`]' fields.
118    //!
119    //! [`Attrs`]: super::Attrs
120
121    use sealed::sealed;
122
123    use crate::field;
124
125    use super::{Dedup, Kind};
126
127    /// Applying a value to a [`field::Container`] according to a parsing
128    /// [`Kind`] and [`Dedup`]lication strategy.
129    pub trait TryApply<V, K: Kind + ?Sized, D: Dedup + ?Sized>:
130        field::Container<V>
131    {
132        /// Applies the provided `value` to this [`field::Container`].
133        ///
134        /// # Errors
135        ///
136        /// If this [`field::Container`] refuses to apply the `value` according
137        /// to the [`Dedup`]lication strategy.
138        fn try_apply(&mut self, value: V) -> syn::Result<()>;
139    }
140
141    /// Applying a value to a [`field::Container`] according to a parsing
142    /// [`Kind`] and [`Dedup`]lication strategy from another
143    /// [`field::Container`].
144    pub trait TryApplySelf<V, K: Kind + ?Sized, D: Dedup + ?Sized>:
145        TryApply<V, K, D>
146    {
147        /// Applies the value extracted from `another` [`field::Container`] to
148        /// this [`field::Container`].
149        ///
150        /// # Errors
151        ///
152        /// If this [`field::Container`] refuses to apply the extracted value
153        /// according to the [`Dedup`]lication strategy.
154        fn try_apply_self(&mut self, another: Self) -> syn::Result<()>;
155    }
156
157    mod option {
158        //! [`TryApply`] impls for [`Option`].
159
160        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        //! [`TryApply`] impls for [`Required`].
220
221        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        //! [`TryApply`] impls for [`Vec`].
281
282        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        //! [`TryApply`] impls for [`HashSet`].
378
379        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        //! [`TryApply`] impls for [`BTreeSet`].
500
501        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        //! [`TryApply`] impls for [`HashMap`].
599
600        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        //! [`TryApply`] impls for [`BTreeMap`].
664
665        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    /// [`TryApply`] and [`TryApplySelf`] traits' shim allowing to specify a
725    /// parsing [`Kind`] and [`Dedup`]lication strategy as method's type
726    /// parameters.
727    #[sealed]
728    pub trait TryMerge<V> {
729        /// Merges the provided `value` to this [`field::Container`] with the
730        /// specified parsing [`Kind`] and [`Dedup`]lication strategy.
731        ///
732        /// # Errors
733        ///
734        /// If this [`field::Container`] refuses to apply the `value` according
735        /// to the [`Dedup`]lication strategy.
736        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        /// Merges the value extracted from `another` [`field::Container`] to
743        /// this [`field::Container`] with the specified parsing [`Kind`] and
744        /// [`Dedup`]lication strategy.
745        ///
746        /// # Errors
747        ///
748        /// If this [`field::Container`] refuses to apply the extracted value
749        /// according to the [`Dedup`]lication strategy.
750        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    //! Kinds of an [`Attrs`]' field parsing.
781    //!
782    //! [`Attrs`]: super::Attrs
783
784    use sealed::sealed;
785
786    /// Abstracted kind of an [`Attrs`]' field parsing into a
787    /// [`field::Container`].
788    ///
789    /// [`Attrs`]: super::Attrs
790    /// [`field::Container`]: crate::field::Container
791    #[sealed]
792    pub trait Kind {}
793
794    /// [`Kind`]s allowing to parse only a single value of an [`Attrs`]' field.
795    ///
796    /// [`Attrs`]: super::Attrs
797    #[sealed]
798    pub trait Single {}
799
800    /// [`Kind`] defining parsing an [`Attrs`]' field as a simple
801    /// [`syn::Ident`].
802    ///
803    /// ```text
804    /// #[attr(ident)]
805    /// ```
806    ///
807    /// [`Attrs`]: super::Attrs
808    /// [`syn::Ident`]: struct@syn::Ident
809    #[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    /// [`Kind`] defining parsing an [`Attrs`]' field as nested [`Attrs`].
819    ///
820    /// ```text
821    /// #[attr(nested(ident, key = val))]
822    /// ```
823    ///
824    /// [`Attrs`]: super::Attrs
825    #[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    /// [`Kind`] defining parsing an [`Attrs`]' field as values behind a
835    /// [`syn::Ident`].
836    ///
837    /// ```text
838    /// #[attr(ident = value)]
839    /// #[attr(ident value)]
840    /// #[attr(ident(value1, value2))]
841    /// ```
842    ///
843    /// [`Attrs`]: super::Attrs
844    /// [`syn::Ident`]: struct@syn::Ident
845    #[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    /// [`Kind`] defining parsing an [`Attrs`]' field as key-value pairs behind
855    /// a [`syn::Ident`].
856    ///
857    /// ```text
858    /// #[attr(ident key = value)]
859    /// ```
860    ///
861    /// [`Attrs`]: super::Attrs
862    /// [`syn::Ident`]: struct@syn::Ident
863    #[derive(Clone, Copy, Debug)]
864    pub enum Map {}
865
866    #[sealed]
867    impl Kind for Map {}
868}
869
870pub mod dedup {
871    //! Deduplication strategies of an [`Attrs`]' field parsing.
872    //!
873    //! [`Attrs`]: super::Attrs
874
875    use sealed::sealed;
876
877    /// Abstracted deduplication strategy of an [`Attrs`]' field parsing into a
878    /// [`field::Container`].
879    ///
880    /// [`Attrs`]: super::Attrs
881    /// [`field::Container`]: crate::field::Container
882    #[sealed]
883    pub trait Dedup {}
884
885    /// [`Dedup`]lication strategy allowing only a single value of an [`Attrs`]'
886    /// field to appear.
887    ///
888    /// [`Attrs`]: super::Attrs
889    #[derive(Clone, Copy, Debug)]
890    pub enum Unique {}
891
892    #[sealed]
893    impl Dedup for Unique {}
894
895    /// [`Dedup`]lication strategy picking only the first parsed value of an
896    /// [`Attrs`]' field.
897    ///
898    /// [`Attrs`]: super::Attrs
899    #[derive(Clone, Copy, Debug)]
900    pub enum First {}
901
902    #[sealed]
903    impl Dedup for First {}
904
905    /// [`Dedup`]lication strategy picking only the last parsed value of an
906    /// [`Attrs`]' field.
907    ///
908    /// [`Attrs`]: super::Attrs
909    #[derive(Clone, Copy, Debug)]
910    pub enum Last {}
911
912    #[sealed]
913    impl Dedup for Last {}
914}
915
916pub mod validate {
917    //! Validation machinery of an [`Attrs`]' field parsing.
918    //!
919    //! [`Attrs`]: super::Attrs
920
921    use sealed::sealed;
922
923    #[doc(inline)]
924    pub use self::rule::Rule;
925
926    /// Validation of a [`Rule`] during an [`Attrs`]' field parsing into a
927    /// [`field::Container`].
928    ///
929    /// [`Attrs`]: super::Attrs
930    /// [`field::Container`]: crate::field::Container
931    pub trait Validation<R: Rule + ?Sized> {
932        /// Checks whether the validation [`Rule`] is satisfied.
933        ///
934        /// # Errors
935        ///
936        /// If validation fails.
937        fn validation(&self) -> syn::Result<()>;
938    }
939
940    mod option {
941        //! Implementations of [`Validation`] for [`Option`].
942
943        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        //! Implementations of [`Validation`] for [`Required`].
954
955        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        //! Implementations of [`Validation`] for [`Vec`].
975
976        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        //! Implementations of [`Validation`] for [`HashSet`].
987
988        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        //! Implementations of [`Validation`] for [`BTreeSet`].
1008
1009        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        //! Implementations of [`Validation`] for [`HashMap`].
1022
1023        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        //! Implementations of [`Validation`] for [`BTreeMap`].
1043
1044        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    /// [`Validation`] trait's shim allowing to specify its [`Rule`] as a
1056    /// method's type parameter.
1057    #[sealed]
1058    pub trait Validate {
1059        /// Checks whether the specified validation [`Rule`] is satisfied.
1060        ///
1061        /// # Errors
1062        ///
1063        /// If validation fails.
1064        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        //! Validation [`Rule`]s of an [`Attrs`]' field parsing.
1081        //!
1082        //! [`Attrs`]: super::super::Attrs
1083
1084        use sealed::sealed;
1085
1086        /// Abstracted validation rule of an [`Attrs`]' field parsing.
1087        ///
1088        /// [`Attrs`]: super::super::Attrs
1089        #[sealed]
1090        pub trait Rule {}
1091
1092        /// Validation [`Rule`] verifying whether an [`Attrs`]' field has been
1093        /// provided for parsing.
1094        ///
1095        /// [`Attrs`]: super::super::Attrs
1096        #[derive(Clone, Copy, Debug)]
1097        pub enum Provided {}
1098
1099        #[sealed]
1100        impl Rule for Provided {}
1101    }
1102}