options/
builder.rs

1use crate::{ConfigureOptions, PostConfigureOptions, ValidateOptions, ValidateOptionsResult};
2use di::{singleton_factory, transient_factory, ServiceCollection, Ref};
3use std::ops::{Deref, DerefMut};
4use std::{marker::PhantomData, rc::Rc};
5
6/// Represents a builder used to configure [`Options`](crate::Options).
7pub struct OptionsBuilder<'a, T: 'static> {
8    name: Option<String>,
9    services: &'a mut ServiceCollection,
10    _marker: PhantomData<T>,
11}
12
13impl<'a, T: 'static> OptionsBuilder<'a, T> {
14    /// Initializes a new options builder.
15    ///
16    /// # Arguments
17    ///
18    /// * `services` - The associated [collection of services](di::ServiceCollection)
19    /// * `name` - The optional name associated with the options
20    pub fn new(services: &'a mut ServiceCollection, name: Option<&str>) -> Self {
21        Self {
22            name: name.map(|s| s.to_owned()),
23            services,
24            _marker: PhantomData,
25        }
26    }
27
28    /// Gets the name of the options
29    pub fn name(&self) -> Option<&str> {
30        self.name.as_deref()
31    }
32
33    /// Gets the associated [collection of services](di::ServiceCollection)
34    pub fn services(&mut self) -> &mut ServiceCollection {
35        self.services
36    }
37
38    /// Registers an action used to configure a particular type of [`Options`](crate::Options).
39    ///
40    /// # Arguments
41    ///
42    /// * `setup` - The configuration action
43    pub fn configure<F>(self, setup: F) -> Self
44    where
45        F: Fn(&mut T) + 'static,
46    {
47        let configure = _Configure::new(self.name.clone(), setup);
48        let action: Ref<dyn ConfigureOptions<T>> = Ref::new(configure);
49        let descriptor = singleton_factory(move |_| action.clone());
50        self.services.add(descriptor);
51        self
52    }
53
54    /// Registers an action used to configure a particular type of [`Options`](crate::Options) with a single dependency.
55    ///
56    /// # Arguments
57    ///
58    /// * `setup` - The configuration action
59    pub fn configure1<F, D>(self, setup: F) -> Self
60    where
61        F: Fn(&mut T, Ref<D>) + 'static,
62        D: 'static,
63    {
64        let action = Rc::new(setup);
65        let name = self.name.clone();
66
67        self.services.add(transient_factory(move |sp| {
68            let config: Ref<dyn ConfigureOptions<T>> = Ref::new(_Configure1::new(
69                name.clone(),
70                sp.get_required::<D>(),
71                action.clone(),
72            ));
73            config
74        }));
75
76        self
77    }
78
79    /// Registers an action used to configure a particular type of [`Options`](crate::Options) with two dependencies.
80    ///
81    /// # Arguments
82    ///
83    /// * `setup` - The configuration action
84    pub fn configure2<F, D1, D2>(self, setup: F) -> Self
85    where
86        F: Fn(&mut T, Ref<D1>, Ref<D2>) + 'static,
87        D1: 'static,
88        D2: 'static,
89    {
90        let action = Rc::new(setup);
91        let name = self.name.clone();
92
93        self.services.add(transient_factory(move |sp| {
94            let config: Ref<dyn ConfigureOptions<T>> = Ref::new(_Configure2::new(
95                name.clone(),
96                sp.get_required::<D1>(),
97                sp.get_required::<D2>(),
98                action.clone(),
99            ));
100            config
101        }));
102
103        self
104    }
105
106    /// Registers an action used to configure a particular type of [`Options`](crate::Options) with three dependencies.
107    ///
108    /// # Arguments
109    ///
110    /// * `setup` - The configuration action
111    pub fn configure3<F, D1, D2, D3>(self, setup: F) -> Self
112    where
113        F: Fn(&mut T, Ref<D1>, Ref<D2>, Ref<D3>) + 'static,
114        D1: 'static,
115        D2: 'static,
116        D3: 'static,
117    {
118        let action = Rc::new(setup);
119        let name = self.name.clone();
120
121        self.services.add(transient_factory(move |sp| {
122            let config: Ref<dyn ConfigureOptions<T>> = Ref::new(_Configure3::new(
123                name.clone(),
124                sp.get_required::<D1>(),
125                sp.get_required::<D2>(),
126                sp.get_required::<D3>(),
127                action.clone(),
128            ));
129            config
130        }));
131
132        self
133    }
134
135    /// Registers an action used to configure a particular type of [`Options`](crate::Options) with four dependencies.
136    ///
137    /// # Arguments
138    ///
139    /// * `setup` - The configuration action
140    pub fn configure4<F, D1, D2, D3, D4>(self, setup: F) -> Self
141    where
142        F: Fn(&mut T, Ref<D1>, Ref<D2>, Ref<D3>, Ref<D4>) + 'static,
143        D1: 'static,
144        D2: 'static,
145        D3: 'static,
146        D4: 'static,
147    {
148        let action = Rc::new(setup);
149        let name = self.name.clone();
150
151        self.services.add(transient_factory(move |sp| {
152            let config: Ref<dyn ConfigureOptions<T>> = Ref::new(_Configure4::new(
153                name.clone(),
154                sp.get_required::<D1>(),
155                sp.get_required::<D2>(),
156                sp.get_required::<D3>(),
157                sp.get_required::<D4>(),
158                action.clone(),
159            ));
160            config
161        }));
162
163        self
164    }
165
166    /// Registers an action used to configure a particular type of [`Options`](crate::Options) with five dependencies.
167    ///
168    /// # Arguments
169    ///
170    /// * `setup` - The configuration action
171    pub fn configure5<F, D1, D2, D3, D4, D5>(self, setup: F) -> Self
172    where
173        F: Fn(
174                &mut T,
175                Ref<D1>,
176                Ref<D2>,
177                Ref<D3>,
178                Ref<D4>,
179                Ref<D5>,
180            ) + 'static,
181        D1: 'static,
182        D2: 'static,
183        D3: 'static,
184        D4: 'static,
185        D5: 'static,
186    {
187        let action = Rc::new(setup);
188        let name = self.name.clone();
189
190        self.services.add(transient_factory(move |sp| {
191            let config: Ref<dyn ConfigureOptions<T>> = Ref::new(_Configure5::new(
192                name.clone(),
193                sp.get_required::<D1>(),
194                sp.get_required::<D2>(),
195                sp.get_required::<D3>(),
196                sp.get_required::<D4>(),
197                sp.get_required::<D5>(),
198                action.clone(),
199            ));
200            config
201        }));
202
203        self
204    }
205
206    /// Registers an action used to configure a particular type of [`Options`](crate::Options).
207    ///
208    /// # Arguments
209    ///
210    /// * `setup` - The configuration action
211    pub fn post_configure<F>(self, setup: F) -> Self
212    where
213        F: Fn(&mut T) + 'static,
214    {
215        let configure = _Configure::new(self.name.clone(), setup);
216        let action: Ref<dyn PostConfigureOptions<T>> = Ref::new(configure);
217        let descriptor = singleton_factory(move |_| action.clone());
218        self.services.add(descriptor);
219        self
220    }
221
222    /// Registers an action used to configure a particular type of [`Options`](crate::Options) with a single dependency.
223    ///
224    /// # Arguments
225    ///
226    /// * `setup` - The configuration action
227    pub fn post_configure1<F, D>(self, setup: F) -> Self
228    where
229        F: Fn(&mut T, Ref<D>) + 'static,
230        D: 'static,
231    {
232        let action = Rc::new(setup);
233        let name = self.name.clone();
234
235        self.services.add(transient_factory(move |sp| {
236            let config: Ref<dyn PostConfigureOptions<T>> = Ref::new(
237                _Configure1::new(name.clone(), sp.get_required::<D>(), action.clone()),
238            );
239            config
240        }));
241
242        self
243    }
244
245    /// Registers an action used to configure a particular type of [`Options`](crate::Options) with two dependencies.
246    ///
247    /// # Arguments
248    ///
249    /// * `setup` - The configuration action
250    pub fn post_configure2<F, D1, D2>(self, setup: F) -> Self
251    where
252        F: Fn(&mut T, Ref<D1>, Ref<D2>) + 'static,
253        D1: 'static,
254        D2: 'static,
255    {
256        let action = Rc::new(setup);
257        let name = self.name.clone();
258
259        self.services.add(transient_factory(move |sp| {
260            let config: Ref<dyn PostConfigureOptions<T>> =
261                Ref::new(_Configure2::new(
262                    name.clone(),
263                    sp.get_required::<D1>(),
264                    sp.get_required::<D2>(),
265                    action.clone(),
266                ));
267            config
268        }));
269
270        self
271    }
272
273    /// Registers an action used to configure a particular type of [`Options`](crate::Options) with three dependencies.
274    ///
275    /// # Arguments
276    ///
277    /// * `setup` - The configuration action
278    pub fn post_configure3<F, D1, D2, D3>(self, setup: F) -> Self
279    where
280        F: Fn(&mut T, Ref<D1>, Ref<D2>, Ref<D3>) + 'static,
281        D1: 'static,
282        D2: 'static,
283        D3: 'static,
284    {
285        let action = Rc::new(setup);
286        let name = self.name.clone();
287
288        self.services.add(transient_factory(move |sp| {
289            let config: Ref<dyn PostConfigureOptions<T>> =
290                Ref::new(_Configure3::new(
291                    name.clone(),
292                    sp.get_required::<D1>(),
293                    sp.get_required::<D2>(),
294                    sp.get_required::<D3>(),
295                    action.clone(),
296                ));
297            config
298        }));
299
300        self
301    }
302
303    /// Registers an action used to configure a particular type of [`Options`](crate::Options) with four dependencies.
304    ///
305    /// # Arguments
306    ///
307    /// * `setup` - The configuration action
308    pub fn post_configure4<F, D1, D2, D3, D4>(self, setup: F) -> Self
309    where
310        F: Fn(&mut T, Ref<D1>, Ref<D2>, Ref<D3>, Ref<D4>) + 'static,
311        D1: 'static,
312        D2: 'static,
313        D3: 'static,
314        D4: 'static,
315    {
316        let action = Rc::new(setup);
317        let name = self.name.clone();
318
319        self.services.add(transient_factory(move |sp| {
320            let config: Ref<dyn PostConfigureOptions<T>> =
321                Ref::new(_Configure4::new(
322                    name.clone(),
323                    sp.get_required::<D1>(),
324                    sp.get_required::<D2>(),
325                    sp.get_required::<D3>(),
326                    sp.get_required::<D4>(),
327                    action.clone(),
328                ));
329            config
330        }));
331
332        self
333    }
334
335    /// Registers an action used to configure a particular type of [`Options`](crate::Options) with five dependencies.
336    ///
337    /// # Arguments
338    ///
339    /// * `setup` - The configuration action
340    pub fn post_configure5<F, D1, D2, D3, D4, D5>(self, setup: F) -> Self
341    where
342        F: Fn(
343                &mut T,
344                Ref<D1>,
345                Ref<D2>,
346                Ref<D3>,
347                Ref<D4>,
348                Ref<D5>,
349            ) + 'static,
350        D1: 'static,
351        D2: 'static,
352        D3: 'static,
353        D4: 'static,
354        D5: 'static,
355    {
356        let action = Rc::new(setup);
357        let name = self.name.clone();
358
359        self.services.add(transient_factory(move |sp| {
360            let config: Ref<dyn PostConfigureOptions<T>> =
361                Ref::new(_Configure5::new(
362                    name.clone(),
363                    sp.get_required::<D1>(),
364                    sp.get_required::<D2>(),
365                    sp.get_required::<D3>(),
366                    sp.get_required::<D4>(),
367                    sp.get_required::<D5>(),
368                    action.clone(),
369                ));
370            config
371        }));
372
373        self
374    }
375
376    /// Registers an action used to validate a particular type of [`Options`](crate::Options).
377    ///
378    /// # Arguments
379    ///
380    /// * `action` - The validation action
381    /// * `failure_message` - The message used when validation fails
382    pub fn validate<F, M>(self, action: F, failure_message: M) -> Self
383    where
384        F: Fn(&T) -> bool + 'static,
385        M: AsRef<str>,
386    {
387        let validate = _Validate::new(
388            self.name.clone(),
389            message_or_default(failure_message),
390            action,
391        );
392        let action: Ref<dyn ValidateOptions<T>> = Ref::new(validate);
393        let descriptor = transient_factory(move |_| action.clone());
394        self.services.add(descriptor);
395        self
396    }
397
398    /// Registers an action used to validate a particular type of [`Options`](crate::Options) with a single dependency.
399    ///
400    /// # Arguments
401    ///
402    /// * `action` - The validation action
403    /// * `failure_message` - The message used when validation fails
404    pub fn validate1<F, M, D>(self, action: F, failure_message: M) -> Self
405    where
406        F: Fn(&T, Ref<D>) -> bool + 'static,
407        M: AsRef<str>,
408        D: 'static,
409    {
410        let action = Rc::new(action);
411        let name = self.name.clone();
412        let failure_message = message_or_default(failure_message);
413
414        self.services.add(transient_factory(move |sp| {
415            let validate: Ref<dyn ValidateOptions<T>> = Ref::new(_Validate1::new(
416                name.clone(),
417                failure_message.clone(),
418                sp.get_required::<D>(),
419                action.clone(),
420            ));
421            validate
422        }));
423
424        self
425    }
426
427    /// Registers an action used to validate a particular type of [`Options`](crate::Options) with two dependencies.
428    ///
429    /// # Arguments
430    ///
431    /// * `action` - The validation action
432    /// * `failure_message` - The message used when validation fails
433    pub fn validate2<F, M, D1, D2>(self, action: F, failure_message: M) -> Self
434    where
435        F: Fn(&T, Ref<D1>, Ref<D2>) -> bool + 'static,
436        M: AsRef<str>,
437        D1: 'static,
438        D2: 'static,
439    {
440        let action = Rc::new(action);
441        let name = self.name.clone();
442        let failure_message = message_or_default(failure_message);
443
444        self.services.add(transient_factory(move |sp| {
445            let validate: Ref<dyn ValidateOptions<T>> = Ref::new(_Validate2::new(
446                name.clone(),
447                failure_message.clone(),
448                sp.get_required::<D1>(),
449                sp.get_required::<D2>(),
450                action.clone(),
451            ));
452            validate
453        }));
454
455        self
456    }
457
458    /// Registers an action used to validate a particular type of [`Options`](crate::Options) with three dependencies.
459    ///
460    /// # Arguments
461    ///
462    /// * `action` - The validation action
463    /// * `failure_message` - The message used when validation fails
464    pub fn validate3<F, M, D1, D2, D3>(self, action: F, failure_message: M) -> Self
465    where
466        F: Fn(&T, Ref<D1>, Ref<D2>, Ref<D3>) -> bool + 'static,
467        M: AsRef<str>,
468        D1: 'static,
469        D2: 'static,
470        D3: 'static,
471    {
472        let action = Rc::new(action);
473        let name = self.name.clone();
474        let failure_message = message_or_default(failure_message);
475
476        self.services.add(transient_factory(move |sp| {
477            let validate: Ref<dyn ValidateOptions<T>> = Ref::new(_Validate3::new(
478                name.clone(),
479                failure_message.clone(),
480                sp.get_required::<D1>(),
481                sp.get_required::<D2>(),
482                sp.get_required::<D3>(),
483                action.clone(),
484            ));
485            validate
486        }));
487
488        self
489    }
490
491    /// Registers an action used to validate a particular type of [`Options`](crate::Options) with four dependencies.
492    ///
493    /// # Arguments
494    ///
495    /// * `action` - The validation action
496    /// * `failure_message` - The message used when validation fails
497    pub fn validate4<F, M, D1, D2, D3, D4>(self, action: F, failure_message: M) -> Self
498    where
499        F: Fn(&T, Ref<D1>, Ref<D2>, Ref<D3>, Ref<D4>) -> bool + 'static,
500        M: AsRef<str>,
501        D1: 'static,
502        D2: 'static,
503        D3: 'static,
504        D4: 'static,
505    {
506        let action = Rc::new(action);
507        let name = self.name.clone();
508        let failure_message = message_or_default(failure_message);
509
510        self.services.add(transient_factory(move |sp| {
511            let validate: Ref<dyn ValidateOptions<T>> = Ref::new(_Validate4::new(
512                name.clone(),
513                failure_message.clone(),
514                sp.get_required::<D1>(),
515                sp.get_required::<D2>(),
516                sp.get_required::<D3>(),
517                sp.get_required::<D4>(),
518                action.clone(),
519            ));
520            validate
521        }));
522
523        self
524    }
525
526    /// Registers an action used to validate a particular type of [`Options`](crate::Options) with five dependencies.
527    ///
528    /// # Arguments
529    ///
530    /// * `action` - The validation action
531    /// * `failure_message` - The message used when validation fails
532    pub fn validate5<F, M, D1, D2, D3, D4, D5>(self, action: F, failure_message: M) -> Self
533    where
534        F: Fn(
535                &T,
536                Ref<D1>,
537                Ref<D2>,
538                Ref<D3>,
539                Ref<D4>,
540                Ref<D5>,
541            ) -> bool
542            + 'static,
543        M: AsRef<str>,
544        D1: 'static,
545        D2: 'static,
546        D3: 'static,
547        D4: 'static,
548        D5: 'static,
549    {
550        let action = Rc::new(action);
551        let name = self.name.clone();
552        let failure_message = message_or_default(failure_message);
553
554        self.services.add(transient_factory(move |sp| {
555            let validate: Ref<dyn ValidateOptions<T>> = Ref::new(_Validate5::new(
556                name.clone(),
557                failure_message.clone(),
558                sp.get_required::<D1>(),
559                sp.get_required::<D2>(),
560                sp.get_required::<D3>(),
561                sp.get_required::<D4>(),
562                sp.get_required::<D5>(),
563                action.clone(),
564            ));
565            validate
566        }));
567
568        self
569    }
570}
571
572fn names_equal(name: Option<&str>, other_name: Option<&str>) -> bool {
573    let matches_all = name.is_none();
574
575    if matches_all || name == other_name {
576        return true;
577    } else if other_name.is_none() {
578        return false;
579    }
580
581    let name1 = name.unwrap();
582    let name2 = other_name.unwrap();
583
584    (name1.len() == name2.len())
585        && ((name1.to_uppercase() == name2.to_uppercase())
586            || (name1.to_lowercase() == name2.to_lowercase()))
587}
588
589impl<'a, T> Into<&'a mut ServiceCollection> for OptionsBuilder<'a, T> {
590    fn into(self) -> &'a mut ServiceCollection {
591        self.services
592    }
593}
594
595impl<'a, T> Deref for OptionsBuilder<'a, T> {
596    type Target = ServiceCollection;
597
598    fn deref(&self) -> &Self::Target {
599        self.services
600    }
601}
602
603impl<'a, T> DerefMut for OptionsBuilder<'a, T> {
604    fn deref_mut(&mut self) -> &mut Self::Target {
605        self.services
606    }
607}
608
609struct _Configure<TOptions, TAction>
610where
611    TAction: Fn(&mut TOptions),
612{
613    name: Option<String>,
614    action: TAction,
615    _marker: PhantomData<TOptions>,
616}
617
618impl<TOptions, TAction> _Configure<TOptions, TAction>
619where
620    TAction: Fn(&mut TOptions),
621{
622    fn new(name: Option<String>, action: TAction) -> Self {
623        Self {
624            name,
625            action,
626            _marker: PhantomData,
627        }
628    }
629}
630
631impl<TOptions, TAction> ConfigureOptions<TOptions> for _Configure<TOptions, TAction>
632where
633    TAction: Fn(&mut TOptions),
634{
635    fn configure(&self, name: Option<&str>, options: &mut TOptions) {
636        if names_equal(self.name.as_deref(), name) {
637            (self.action)(options)
638        }
639    }
640}
641
642impl<TOptions, TAction> PostConfigureOptions<TOptions> for _Configure<TOptions, TAction>
643where
644    TAction: Fn(&mut TOptions),
645{
646    fn post_configure(&self, name: Option<&str>, options: &mut TOptions) {
647        if names_equal(self.name.as_deref(), name) {
648            (self.action)(options)
649        }
650    }
651}
652
653struct _Configure1<TOptions, TAction, TDep>
654where
655    TAction: Fn(&mut TOptions, Ref<TDep>),
656{
657    name: Option<String>,
658    action: Rc<TAction>,
659    dependency: Ref<TDep>,
660    _marker: PhantomData<TOptions>,
661}
662
663impl<TOptions, TAction, TDep> _Configure1<TOptions, TAction, TDep>
664where
665    TAction: Fn(&mut TOptions, Ref<TDep>),
666{
667    fn new(name: Option<String>, dependency: Ref<TDep>, action: Rc<TAction>) -> Self {
668        Self {
669            name,
670            action,
671            dependency,
672            _marker: PhantomData,
673        }
674    }
675}
676
677impl<TOptions, TAction, TDep> ConfigureOptions<TOptions> for _Configure1<TOptions, TAction, TDep>
678where
679    TAction: Fn(&mut TOptions, Ref<TDep>),
680{
681    fn configure(&self, name: Option<&str>, options: &mut TOptions) {
682        if names_equal(self.name.as_deref(), name) {
683            (self.action)(options, self.dependency.clone())
684        }
685    }
686}
687
688impl<TOptions, TAction, TDep> PostConfigureOptions<TOptions>
689    for _Configure1<TOptions, TAction, TDep>
690where
691    TAction: Fn(&mut TOptions, Ref<TDep>),
692{
693    fn post_configure(&self, name: Option<&str>, options: &mut TOptions) {
694        if names_equal(self.name.as_deref(), name) {
695            (self.action)(options, self.dependency.clone())
696        }
697    }
698}
699
700struct _Configure2<TOptions, TAction, TDep1, TDep2>
701where
702    TAction: Fn(&mut TOptions, Ref<TDep1>, Ref<TDep2>),
703{
704    name: Option<String>,
705    action: Rc<TAction>,
706    dependency1: Ref<TDep1>,
707    dependency2: Ref<TDep2>,
708    _marker: PhantomData<TOptions>,
709}
710
711impl<TOptions, TAction, TDep1, TDep2> _Configure2<TOptions, TAction, TDep1, TDep2>
712where
713    TAction: Fn(&mut TOptions, Ref<TDep1>, Ref<TDep2>),
714{
715    fn new(
716        name: Option<String>,
717        dependency1: Ref<TDep1>,
718        dependency2: Ref<TDep2>,
719        action: Rc<TAction>,
720    ) -> Self {
721        Self {
722            name,
723            action,
724            dependency1,
725            dependency2,
726            _marker: PhantomData,
727        }
728    }
729}
730
731impl<TOptions, TAction, TDep1, TDep2> ConfigureOptions<TOptions>
732    for _Configure2<TOptions, TAction, TDep1, TDep2>
733where
734    TAction: Fn(&mut TOptions, Ref<TDep1>, Ref<TDep2>),
735{
736    fn configure(&self, name: Option<&str>, options: &mut TOptions) {
737        if names_equal(self.name.as_deref(), name) {
738            (self.action)(options, self.dependency1.clone(), self.dependency2.clone())
739        }
740    }
741}
742
743impl<TOptions, TAction, TDep1, TDep2> PostConfigureOptions<TOptions>
744    for _Configure2<TOptions, TAction, TDep1, TDep2>
745where
746    TAction: Fn(&mut TOptions, Ref<TDep1>, Ref<TDep2>),
747{
748    fn post_configure(&self, name: Option<&str>, options: &mut TOptions) {
749        if names_equal(self.name.as_deref(), name) {
750            (self.action)(options, self.dependency1.clone(), self.dependency2.clone())
751        }
752    }
753}
754
755struct _Configure3<TOptions, TAction, TDep1, TDep2, TDep3>
756where
757    TAction: Fn(&mut TOptions, Ref<TDep1>, Ref<TDep2>, Ref<TDep3>),
758{
759    name: Option<String>,
760    action: Rc<TAction>,
761    dependency1: Ref<TDep1>,
762    dependency2: Ref<TDep2>,
763    dependency3: Ref<TDep3>,
764    _marker: PhantomData<TOptions>,
765}
766
767impl<TOptions, TAction, TDep1, TDep2, TDep3> _Configure3<TOptions, TAction, TDep1, TDep2, TDep3>
768where
769    TAction: Fn(&mut TOptions, Ref<TDep1>, Ref<TDep2>, Ref<TDep3>),
770{
771    fn new(
772        name: Option<String>,
773        dependency1: Ref<TDep1>,
774        dependency2: Ref<TDep2>,
775        dependency3: Ref<TDep3>,
776        action: Rc<TAction>,
777    ) -> Self {
778        Self {
779            name,
780            action,
781            dependency1,
782            dependency2,
783            dependency3,
784            _marker: PhantomData,
785        }
786    }
787}
788
789impl<TOptions, TAction, TDep1, TDep2, TDep3> ConfigureOptions<TOptions>
790    for _Configure3<TOptions, TAction, TDep1, TDep2, TDep3>
791where
792    TAction: Fn(&mut TOptions, Ref<TDep1>, Ref<TDep2>, Ref<TDep3>),
793{
794    fn configure(&self, name: Option<&str>, options: &mut TOptions) {
795        if names_equal(self.name.as_deref(), name) {
796            (self.action)(
797                options,
798                self.dependency1.clone(),
799                self.dependency2.clone(),
800                self.dependency3.clone(),
801            )
802        }
803    }
804}
805
806impl<TOptions, TAction, TDep1, TDep2, TDep3> PostConfigureOptions<TOptions>
807    for _Configure3<TOptions, TAction, TDep1, TDep2, TDep3>
808where
809    TAction: Fn(&mut TOptions, Ref<TDep1>, Ref<TDep2>, Ref<TDep3>),
810{
811    fn post_configure(&self, name: Option<&str>, options: &mut TOptions) {
812        if names_equal(self.name.as_deref(), name) {
813            (self.action)(
814                options,
815                self.dependency1.clone(),
816                self.dependency2.clone(),
817                self.dependency3.clone(),
818            )
819        }
820    }
821}
822
823struct _Configure4<TOptions, TAction, TDep1, TDep2, TDep3, TDep4>
824where
825    TAction: Fn(
826        &mut TOptions,
827        Ref<TDep1>,
828        Ref<TDep2>,
829        Ref<TDep3>,
830        Ref<TDep4>,
831    ),
832{
833    name: Option<String>,
834    action: Rc<TAction>,
835    dependency1: Ref<TDep1>,
836    dependency2: Ref<TDep2>,
837    dependency3: Ref<TDep3>,
838    dependency4: Ref<TDep4>,
839    _marker: PhantomData<TOptions>,
840}
841
842impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4>
843    _Configure4<TOptions, TAction, TDep1, TDep2, TDep3, TDep4>
844where
845    TAction: Fn(
846        &mut TOptions,
847        Ref<TDep1>,
848        Ref<TDep2>,
849        Ref<TDep3>,
850        Ref<TDep4>,
851    ),
852{
853    fn new(
854        name: Option<String>,
855        dependency1: Ref<TDep1>,
856        dependency2: Ref<TDep2>,
857        dependency3: Ref<TDep3>,
858        dependency4: Ref<TDep4>,
859        action: Rc<TAction>,
860    ) -> Self {
861        Self {
862            name,
863            action,
864            dependency1,
865            dependency2,
866            dependency3,
867            dependency4,
868            _marker: PhantomData,
869        }
870    }
871}
872
873impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4> ConfigureOptions<TOptions>
874    for _Configure4<TOptions, TAction, TDep1, TDep2, TDep3, TDep4>
875where
876    TAction: Fn(
877        &mut TOptions,
878        Ref<TDep1>,
879        Ref<TDep2>,
880        Ref<TDep3>,
881        Ref<TDep4>,
882    ),
883{
884    fn configure(&self, name: Option<&str>, options: &mut TOptions) {
885        if names_equal(self.name.as_deref(), name) {
886            (self.action)(
887                options,
888                self.dependency1.clone(),
889                self.dependency2.clone(),
890                self.dependency3.clone(),
891                self.dependency4.clone(),
892            )
893        }
894    }
895}
896
897impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4> PostConfigureOptions<TOptions>
898    for _Configure4<TOptions, TAction, TDep1, TDep2, TDep3, TDep4>
899where
900    TAction: Fn(
901        &mut TOptions,
902        Ref<TDep1>,
903        Ref<TDep2>,
904        Ref<TDep3>,
905        Ref<TDep4>,
906    ),
907{
908    fn post_configure(&self, name: Option<&str>, options: &mut TOptions) {
909        if names_equal(self.name.as_deref(), name) {
910            (self.action)(
911                options,
912                self.dependency1.clone(),
913                self.dependency2.clone(),
914                self.dependency3.clone(),
915                self.dependency4.clone(),
916            )
917        }
918    }
919}
920
921struct _Configure5<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5>
922where
923    TAction: Fn(
924        &mut TOptions,
925        Ref<TDep1>,
926        Ref<TDep2>,
927        Ref<TDep3>,
928        Ref<TDep4>,
929        Ref<TDep5>,
930    ),
931{
932    name: Option<String>,
933    action: Rc<TAction>,
934    dependency1: Ref<TDep1>,
935    dependency2: Ref<TDep2>,
936    dependency3: Ref<TDep3>,
937    dependency4: Ref<TDep4>,
938    dependency5: Ref<TDep5>,
939    _marker: PhantomData<TOptions>,
940}
941
942impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5>
943    _Configure5<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5>
944where
945    TAction: Fn(
946        &mut TOptions,
947        Ref<TDep1>,
948        Ref<TDep2>,
949        Ref<TDep3>,
950        Ref<TDep4>,
951        Ref<TDep5>,
952    ),
953{
954    fn new(
955        name: Option<String>,
956        dependency1: Ref<TDep1>,
957        dependency2: Ref<TDep2>,
958        dependency3: Ref<TDep3>,
959        dependency4: Ref<TDep4>,
960        dependency5: Ref<TDep5>,
961        action: Rc<TAction>,
962    ) -> Self {
963        Self {
964            name,
965            action,
966            dependency1,
967            dependency2,
968            dependency3,
969            dependency4,
970            dependency5,
971            _marker: PhantomData,
972        }
973    }
974}
975
976impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5> ConfigureOptions<TOptions>
977    for _Configure5<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5>
978where
979    TAction: Fn(
980        &mut TOptions,
981        Ref<TDep1>,
982        Ref<TDep2>,
983        Ref<TDep3>,
984        Ref<TDep4>,
985        Ref<TDep5>,
986    ),
987{
988    fn configure(&self, name: Option<&str>, options: &mut TOptions) {
989        if names_equal(self.name.as_deref(), name) {
990            (self.action)(
991                options,
992                self.dependency1.clone(),
993                self.dependency2.clone(),
994                self.dependency3.clone(),
995                self.dependency4.clone(),
996                self.dependency5.clone(),
997            )
998        }
999    }
1000}
1001
1002impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5> PostConfigureOptions<TOptions>
1003    for _Configure5<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5>
1004where
1005    TAction: Fn(
1006        &mut TOptions,
1007        Ref<TDep1>,
1008        Ref<TDep2>,
1009        Ref<TDep3>,
1010        Ref<TDep4>,
1011        Ref<TDep5>,
1012    ),
1013{
1014    fn post_configure(&self, name: Option<&str>, options: &mut TOptions) {
1015        if names_equal(self.name.as_deref(), name) {
1016            (self.action)(
1017                options,
1018                self.dependency1.clone(),
1019                self.dependency2.clone(),
1020                self.dependency3.clone(),
1021                self.dependency4.clone(),
1022                self.dependency5.clone(),
1023            )
1024        }
1025    }
1026}
1027
1028fn message_or_default<T: AsRef<str>>(message: T) -> String {
1029    let msg = message.as_ref();
1030
1031    if msg.is_empty() {
1032        String::from("A validation error has occurred.")
1033    } else {
1034        String::from(msg)
1035    }
1036}
1037
1038struct _Validate<TOptions, TAction>
1039where
1040    TAction: Fn(&TOptions) -> bool,
1041{
1042    name: Option<String>,
1043    failure_message: String,
1044    action: TAction,
1045    _marker: PhantomData<TOptions>,
1046}
1047
1048impl<TOptions, TAction> _Validate<TOptions, TAction>
1049where
1050    TAction: Fn(&TOptions) -> bool,
1051{
1052    fn new(name: Option<String>, failure_message: String, action: TAction) -> Self {
1053        Self {
1054            name,
1055            failure_message,
1056            action,
1057            _marker: PhantomData,
1058        }
1059    }
1060}
1061
1062impl<TOptions, TAction> ValidateOptions<TOptions> for _Validate<TOptions, TAction>
1063where
1064    TAction: Fn(&TOptions) -> bool,
1065{
1066    fn validate(&self, name: Option<&str>, options: &TOptions) -> ValidateOptionsResult {
1067        if names_equal(self.name.as_deref(), name) {
1068            if (self.action)(options) {
1069                return ValidateOptionsResult::success();
1070            } else {
1071                return ValidateOptionsResult::fail(&self.failure_message);
1072            }
1073        }
1074
1075        return ValidateOptionsResult::skip();
1076    }
1077}
1078
1079struct _Validate1<TOptions, TAction, TDep>
1080where
1081    TAction: Fn(&TOptions, Ref<TDep>) -> bool,
1082{
1083    name: Option<String>,
1084    failure_message: String,
1085    action: Rc<TAction>,
1086    dependency1: Ref<TDep>,
1087    _marker: PhantomData<TOptions>,
1088}
1089
1090impl<TOptions, TAction, TDep> _Validate1<TOptions, TAction, TDep>
1091where
1092    TAction: Fn(&TOptions, Ref<TDep>) -> bool,
1093{
1094    fn new(
1095        name: Option<String>,
1096        failure_message: String,
1097        dependency1: Ref<TDep>,
1098        action: Rc<TAction>,
1099    ) -> Self {
1100        Self {
1101            name,
1102            failure_message,
1103            action,
1104            dependency1,
1105            _marker: PhantomData,
1106        }
1107    }
1108}
1109
1110impl<TOptions, TAction, TDep> ValidateOptions<TOptions> for _Validate1<TOptions, TAction, TDep>
1111where
1112    TAction: Fn(&TOptions, Ref<TDep>) -> bool,
1113{
1114    fn validate(&self, name: Option<&str>, options: &TOptions) -> ValidateOptionsResult {
1115        if names_equal(self.name.as_deref(), name) {
1116            if (self.action)(options, self.dependency1.clone()) {
1117                return ValidateOptionsResult::success();
1118            } else {
1119                return ValidateOptionsResult::fail(&self.failure_message);
1120            }
1121        }
1122
1123        return ValidateOptionsResult::skip();
1124    }
1125}
1126
1127struct _Validate2<TOptions, TAction, TDep1, TDep2>
1128where
1129    TAction: Fn(&TOptions, Ref<TDep1>, Ref<TDep2>) -> bool,
1130{
1131    name: Option<String>,
1132    failure_message: String,
1133    action: Rc<TAction>,
1134    dependency1: Ref<TDep1>,
1135    dependency2: Ref<TDep2>,
1136    _marker: PhantomData<TOptions>,
1137}
1138
1139impl<TOptions, TAction, TDep1, TDep2> _Validate2<TOptions, TAction, TDep1, TDep2>
1140where
1141    TAction: Fn(&TOptions, Ref<TDep1>, Ref<TDep2>) -> bool,
1142{
1143    fn new(
1144        name: Option<String>,
1145        failure_message: String,
1146        dependency1: Ref<TDep1>,
1147        dependency2: Ref<TDep2>,
1148        action: Rc<TAction>,
1149    ) -> Self {
1150        Self {
1151            name,
1152            failure_message,
1153            action,
1154            dependency1,
1155            dependency2,
1156            _marker: PhantomData,
1157        }
1158    }
1159}
1160
1161impl<TOptions, TAction, TDep1, TDep2> ValidateOptions<TOptions>
1162    for _Validate2<TOptions, TAction, TDep1, TDep2>
1163where
1164    TAction: Fn(&TOptions, Ref<TDep1>, Ref<TDep2>) -> bool,
1165{
1166    fn validate(&self, name: Option<&str>, options: &TOptions) -> ValidateOptionsResult {
1167        if names_equal(self.name.as_deref(), name) {
1168            if (self.action)(options, self.dependency1.clone(), self.dependency2.clone()) {
1169                return ValidateOptionsResult::success();
1170            } else {
1171                return ValidateOptionsResult::fail(&self.failure_message);
1172            }
1173        }
1174
1175        return ValidateOptionsResult::skip();
1176    }
1177}
1178
1179struct _Validate3<TOptions, TAction, TDep1, TDep2, TDep3>
1180where
1181    TAction: Fn(&TOptions, Ref<TDep1>, Ref<TDep2>, Ref<TDep3>) -> bool,
1182{
1183    name: Option<String>,
1184    failure_message: String,
1185    action: Rc<TAction>,
1186    dependency1: Ref<TDep1>,
1187    dependency2: Ref<TDep2>,
1188    dependency3: Ref<TDep3>,
1189    _marker: PhantomData<TOptions>,
1190}
1191
1192impl<TOptions, TAction, TDep1, TDep2, TDep3> _Validate3<TOptions, TAction, TDep1, TDep2, TDep3>
1193where
1194    TAction: Fn(&TOptions, Ref<TDep1>, Ref<TDep2>, Ref<TDep3>) -> bool,
1195{
1196    fn new(
1197        name: Option<String>,
1198        failure_message: String,
1199        dependency1: Ref<TDep1>,
1200        dependency2: Ref<TDep2>,
1201        dependency3: Ref<TDep3>,
1202        action: Rc<TAction>,
1203    ) -> Self {
1204        Self {
1205            name,
1206            failure_message,
1207            action,
1208            dependency1,
1209            dependency2,
1210            dependency3,
1211            _marker: PhantomData,
1212        }
1213    }
1214}
1215
1216impl<TOptions, TAction, TDep1, TDep2, TDep3> ValidateOptions<TOptions>
1217    for _Validate3<TOptions, TAction, TDep1, TDep2, TDep3>
1218where
1219    TAction: Fn(&TOptions, Ref<TDep1>, Ref<TDep2>, Ref<TDep3>) -> bool,
1220{
1221    fn validate(&self, name: Option<&str>, options: &TOptions) -> ValidateOptionsResult {
1222        if names_equal(self.name.as_deref(), name) {
1223            if (self.action)(
1224                options,
1225                self.dependency1.clone(),
1226                self.dependency2.clone(),
1227                self.dependency3.clone(),
1228            ) {
1229                return ValidateOptionsResult::success();
1230            } else {
1231                return ValidateOptionsResult::fail(&self.failure_message);
1232            }
1233        }
1234
1235        return ValidateOptionsResult::skip();
1236    }
1237}
1238
1239struct _Validate4<TOptions, TAction, TDep1, TDep2, TDep3, TDep4>
1240where
1241    TAction: Fn(
1242        &TOptions,
1243        Ref<TDep1>,
1244        Ref<TDep2>,
1245        Ref<TDep3>,
1246        Ref<TDep4>,
1247    ) -> bool,
1248{
1249    name: Option<String>,
1250    failure_message: String,
1251    action: Rc<TAction>,
1252    dependency1: Ref<TDep1>,
1253    dependency2: Ref<TDep2>,
1254    dependency3: Ref<TDep3>,
1255    dependency4: Ref<TDep4>,
1256    _marker: PhantomData<TOptions>,
1257}
1258
1259impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4>
1260    _Validate4<TOptions, TAction, TDep1, TDep2, TDep3, TDep4>
1261where
1262    TAction: Fn(
1263        &TOptions,
1264        Ref<TDep1>,
1265        Ref<TDep2>,
1266        Ref<TDep3>,
1267        Ref<TDep4>,
1268    ) -> bool,
1269{
1270    fn new(
1271        name: Option<String>,
1272        failure_message: String,
1273        dependency1: Ref<TDep1>,
1274        dependency2: Ref<TDep2>,
1275        dependency3: Ref<TDep3>,
1276        dependency4: Ref<TDep4>,
1277        action: Rc<TAction>,
1278    ) -> Self {
1279        Self {
1280            name,
1281            failure_message,
1282            action,
1283            dependency1,
1284            dependency2,
1285            dependency3,
1286            dependency4,
1287            _marker: PhantomData,
1288        }
1289    }
1290}
1291
1292impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4> ValidateOptions<TOptions>
1293    for _Validate4<TOptions, TAction, TDep1, TDep2, TDep3, TDep4>
1294where
1295    TAction: Fn(
1296        &TOptions,
1297        Ref<TDep1>,
1298        Ref<TDep2>,
1299        Ref<TDep3>,
1300        Ref<TDep4>,
1301    ) -> bool,
1302{
1303    fn validate(&self, name: Option<&str>, options: &TOptions) -> ValidateOptionsResult {
1304        if names_equal(self.name.as_deref(), name) {
1305            if (self.action)(
1306                options,
1307                self.dependency1.clone(),
1308                self.dependency2.clone(),
1309                self.dependency3.clone(),
1310                self.dependency4.clone(),
1311            ) {
1312                return ValidateOptionsResult::success();
1313            } else {
1314                return ValidateOptionsResult::fail(&self.failure_message);
1315            }
1316        }
1317
1318        return ValidateOptionsResult::skip();
1319    }
1320}
1321
1322struct _Validate5<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5>
1323where
1324    TAction: Fn(
1325        &TOptions,
1326        Ref<TDep1>,
1327        Ref<TDep2>,
1328        Ref<TDep3>,
1329        Ref<TDep4>,
1330        Ref<TDep5>,
1331    ) -> bool,
1332{
1333    name: Option<String>,
1334    failure_message: String,
1335    action: Rc<TAction>,
1336    dependency1: Ref<TDep1>,
1337    dependency2: Ref<TDep2>,
1338    dependency3: Ref<TDep3>,
1339    dependency4: Ref<TDep4>,
1340    dependency5: Ref<TDep5>,
1341    _marker: PhantomData<TOptions>,
1342}
1343
1344impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5>
1345    _Validate5<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5>
1346where
1347    TAction: Fn(
1348        &TOptions,
1349        Ref<TDep1>,
1350        Ref<TDep2>,
1351        Ref<TDep3>,
1352        Ref<TDep4>,
1353        Ref<TDep5>,
1354    ) -> bool,
1355{
1356    fn new(
1357        name: Option<String>,
1358        failure_message: String,
1359        dependency1: Ref<TDep1>,
1360        dependency2: Ref<TDep2>,
1361        dependency3: Ref<TDep3>,
1362        dependency4: Ref<TDep4>,
1363        dependency5: Ref<TDep5>,
1364        action: Rc<TAction>,
1365    ) -> Self {
1366        Self {
1367            name,
1368            failure_message,
1369            action,
1370            dependency1,
1371            dependency2,
1372            dependency3,
1373            dependency4,
1374            dependency5,
1375            _marker: PhantomData,
1376        }
1377    }
1378}
1379
1380impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5> ValidateOptions<TOptions>
1381    for _Validate5<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5>
1382where
1383    TAction: Fn(
1384        &TOptions,
1385        Ref<TDep1>,
1386        Ref<TDep2>,
1387        Ref<TDep3>,
1388        Ref<TDep4>,
1389        Ref<TDep5>,
1390    ) -> bool,
1391{
1392    fn validate(&self, name: Option<&str>, options: &TOptions) -> ValidateOptionsResult {
1393        if names_equal(self.name.as_deref(), name) {
1394            if (self.action)(
1395                options,
1396                self.dependency1.clone(),
1397                self.dependency2.clone(),
1398                self.dependency3.clone(),
1399                self.dependency4.clone(),
1400                self.dependency5.clone(),
1401            ) {
1402                return ValidateOptionsResult::success();
1403            } else {
1404                return ValidateOptionsResult::fail(&self.failure_message);
1405            }
1406        }
1407
1408        return ValidateOptionsResult::skip();
1409    }
1410}