Skip to main content

options/
builder.rs

1use crate::{ConfigureOptions, PostConfigureOptions, Ref, ValidateOptions, ValidateOptionsResult, Value};
2use cfg_if::cfg_if;
3use di::{singleton_factory, transient_factory, Ref as Svc, ServiceCollection};
4use std::marker::PhantomData;
5use std::ops::{Deref, DerefMut};
6
7/// Represents a builder used to configure [`Options`](crate::Options).
8pub struct OptionsBuilder<'a, T: 'static> {
9    name: Option<String>,
10    services: &'a mut ServiceCollection,
11    _marker: PhantomData<T>,
12}
13
14impl<'a, T: 'static> OptionsBuilder<'a, T> {
15    /// Initializes a new options builder.
16    ///
17    /// # Arguments
18    ///
19    /// * `services` - The associated [collection of services](di::ServiceCollection)
20    /// * `name` - The optional name associated with the options
21    #[inline]
22    pub fn new(services: &'a mut ServiceCollection, name: Option<&str>) -> Self {
23        Self {
24            name: name.map(|s| s.to_owned()),
25            services,
26            _marker: PhantomData,
27        }
28    }
29
30    /// Gets the name of the options
31    #[inline]
32    pub fn name(&self) -> Option<&str> {
33        self.name.as_deref()
34    }
35
36    /// Gets the associated [collection of services](di::ServiceCollection)    
37    #[inline]
38    pub fn services(&mut self) -> &mut ServiceCollection {
39        self.services
40    }
41}
42
43macro_rules! builder {
44    (($($bounds:tt)+)) => {
45        impl<'a, T: $($bounds)+> OptionsBuilder<'a, T> {
46            /// Registers an action used to configure a particular type of [`Options`](crate::Options).
47            ///
48            /// # Arguments
49            ///
50            /// * `setup` - The configuration action
51            pub fn configure<F>(self, setup: F) -> Self
52            where
53                F: Fn(&mut T) + $($bounds)+,
54            {
55                let configure = _Configure {
56                    name: self.name.clone(),
57                    action: setup,
58                    _marker: PhantomData,
59                };
60                let action: Ref<dyn ConfigureOptions<T>> = Ref::new(configure);
61                let descriptor = singleton_factory(move |_| action.clone());
62                self.services.add(descriptor);
63                self
64            }
65
66            /// Registers an action used to configure a particular type of [`Options`](crate::Options) with a single dependency.
67            ///
68            /// # Arguments
69            ///
70            /// * `setup` - The configuration action
71            pub fn configure1<F, D>(self, setup: F) -> Self
72            where
73                F: Fn(&mut T, Svc<D>) + $($bounds)+,
74                D: $($bounds)+,
75            {
76                let action = Ref::new(setup);
77                let name = self.name.clone();
78
79                self.services.add(transient_factory(move |sp| {
80                    let config: Ref<dyn ConfigureOptions<T>> = Ref::new(_Configure1 {
81                        name: name.clone(),
82                        action: action.clone(),
83                        dependency: sp.get_required::<D>(),
84                        _marker: PhantomData,
85                    });
86                    config
87                }));
88
89                self
90            }
91
92            /// Registers an action used to configure a particular type of [`Options`](crate::Options) with two dependencies.
93            ///
94            /// # Arguments
95            ///
96            /// * `setup` - The configuration action
97            pub fn configure2<F, D1, D2>(self, setup: F) -> Self
98            where
99                F: Fn(&mut T, Svc<D1>, Svc<D2>) + $($bounds)+,
100                D1: $($bounds)+,
101                D2: $($bounds)+,
102            {
103                let action = Ref::new(setup);
104                let name = self.name.clone();
105
106                self.services.add(transient_factory(move |sp| {
107                    let config: Ref<dyn ConfigureOptions<T>> = Ref::new(_Configure2 {
108                        name: name.clone(),
109                        action: action.clone(),
110                        dependency1: sp.get_required::<D1>(),
111                        dependency2: sp.get_required::<D2>(),
112                        _marker: PhantomData,
113                    });
114                    config
115                }));
116
117                self
118            }
119
120            /// Registers an action used to configure a particular type of [`Options`](crate::Options) with three dependencies.
121            ///
122            /// # Arguments
123            ///
124            /// * `setup` - The configuration action
125            pub fn configure3<F, D1, D2, D3>(self, setup: F) -> Self
126            where
127                F: Fn(&mut T, Svc<D1>, Svc<D2>, Svc<D3>) + $($bounds)+,
128                D1: $($bounds)+,
129                D2: $($bounds)+,
130                D3: $($bounds)+,
131            {
132                let action = Ref::new(setup);
133                let name = self.name.clone();
134
135                self.services.add(transient_factory(move |sp| {
136                    let config: Ref<dyn ConfigureOptions<T>> = Ref::new(_Configure3 {
137                        name: name.clone(),
138                        action: action.clone(),
139                        dependency1: sp.get_required::<D1>(),
140                        dependency2: sp.get_required::<D2>(),
141                        dependency3: sp.get_required::<D3>(),
142                        _marker: PhantomData,
143                    });
144                    config
145                }));
146
147                self
148            }
149
150            /// Registers an action used to configure a particular type of [`Options`](crate::Options) with four dependencies.
151            ///
152            /// # Arguments
153            ///
154            /// * `setup` - The configuration action
155            pub fn configure4<F, D1, D2, D3, D4>(self, setup: F) -> Self
156            where
157                F: Fn(&mut T, Svc<D1>, Svc<D2>, Svc<D3>, Svc<D4>) + $($bounds)+,
158                D1: $($bounds)+,
159                D2: $($bounds)+,
160                D3: $($bounds)+,
161                D4: $($bounds)+,
162            {
163                let action = Ref::new(setup);
164                let name = self.name.clone();
165
166                self.services.add(transient_factory(move |sp| {
167                    let config: Ref<dyn ConfigureOptions<T>> = Ref::new(_Configure4 {
168                        name: name.clone(),
169                        action: action.clone(),
170                        dependency1: sp.get_required::<D1>(),
171                        dependency2: sp.get_required::<D2>(),
172                        dependency3: sp.get_required::<D3>(),
173                        dependency4: sp.get_required::<D4>(),
174                        _marker: PhantomData,
175                    });
176                    config
177                }));
178
179                self
180            }
181
182            /// Registers an action used to configure a particular type of [`Options`](crate::Options) with five dependencies.
183            ///
184            /// # Arguments
185            ///
186            /// * `setup` - The configuration action
187            pub fn configure5<F, D1, D2, D3, D4, D5>(self, setup: F) -> Self
188            where
189                F: Fn(&mut T, Svc<D1>, Svc<D2>, Svc<D3>, Svc<D4>, Svc<D5>) + $($bounds)+,
190                D1: $($bounds)+,
191                D2: $($bounds)+,
192                D3: $($bounds)+,
193                D4: $($bounds)+,
194                D5: $($bounds)+,
195            {
196                let action = Ref::new(setup);
197                let name = self.name.clone();
198
199                self.services.add(transient_factory(move |sp| {
200                    let config: Ref<dyn ConfigureOptions<T>> = Ref::new(_Configure5 {
201                        name: name.clone(),
202                        action: action.clone(),
203                        dependency1: sp.get_required::<D1>(),
204                        dependency2: sp.get_required::<D2>(),
205                        dependency3: sp.get_required::<D3>(),
206                        dependency4: sp.get_required::<D4>(),
207                        dependency5: sp.get_required::<D5>(),
208                        _marker: PhantomData,
209                    });
210                    config
211                }));
212
213                self
214            }
215
216            /// Registers an action used to configure a particular type of [`Options`](crate::Options).
217            ///
218            /// # Arguments
219            ///
220            /// * `setup` - The configuration action
221            pub fn post_configure<F>(self, setup: F) -> Self
222            where
223                F: Fn(&mut T) + $($bounds)+,
224            {
225                let configure = _Configure {
226                    name: self.name.clone(),
227                    action: setup,
228                    _marker: PhantomData,
229                };
230                let action: Ref<dyn ConfigureOptions<T>> = Ref::new(configure);
231                let descriptor = singleton_factory(move |_| action.clone());
232                self.services.add(descriptor);
233                self
234            }
235
236            /// Registers an action used to configure a particular type of [`Options`](crate::Options) with a single dependency.
237            ///
238            /// # Arguments
239            ///
240            /// * `setup` - The configuration action
241            pub fn post_configure1<F, D>(self, setup: F) -> Self
242            where
243                F: Fn(&mut T, Svc<D>) + $($bounds)+,
244                D: $($bounds)+,
245            {
246                let action = Ref::new(setup);
247                let name = self.name.clone();
248
249                self.services.add(transient_factory(move |sp| {
250                    let config: Ref<dyn PostConfigureOptions<T>> = Ref::new(_Configure1 {
251                        name: name.clone(),
252                        action: action.clone(),
253                        dependency: sp.get_required::<D>(),
254                        _marker: PhantomData,
255                    });
256                    config
257                }));
258
259                self
260            }
261
262            /// Registers an action used to configure a particular type of [`Options`](crate::Options) with two dependencies.
263            ///
264            /// # Arguments
265            ///
266            /// * `setup` - The configuration action
267            pub fn post_configure2<F, D1, D2>(self, setup: F) -> Self
268            where
269                F: Fn(&mut T, Svc<D1>, Svc<D2>) + $($bounds)+,
270                D1: $($bounds)+,
271                D2: $($bounds)+,
272            {
273                let action = Ref::new(setup);
274                let name = self.name.clone();
275
276                self.services.add(transient_factory(move |sp| {
277                    let config: Ref<dyn PostConfigureOptions<T>> = Ref::new(_Configure2 {
278                        name: name.clone(),
279                        action: action.clone(),
280                        dependency1: sp.get_required::<D1>(),
281                        dependency2: sp.get_required::<D2>(),
282                        _marker: PhantomData,
283                    });
284                    config
285                }));
286
287                self
288            }
289
290            /// Registers an action used to configure a particular type of [`Options`](crate::Options) with three dependencies.
291            ///
292            /// # Arguments
293            ///
294            /// * `setup` - The configuration action
295            pub fn post_configure3<F, D1, D2, D3>(self, setup: F) -> Self
296            where
297                F: Fn(&mut T, Svc<D1>, Svc<D2>, Svc<D3>) + $($bounds)+,
298                D1: $($bounds)+,
299                D2: $($bounds)+,
300                D3: $($bounds)+,
301            {
302                let action = Ref::new(setup);
303                let name = self.name.clone();
304
305                self.services.add(transient_factory(move |sp| {
306                    let config: Ref<dyn PostConfigureOptions<T>> = Ref::new(_Configure3 {
307                        name: name.clone(),
308                        action: action.clone(),
309                        dependency1: sp.get_required::<D1>(),
310                        dependency2: sp.get_required::<D2>(),
311                        dependency3: sp.get_required::<D3>(),
312                        _marker: PhantomData,
313                    });
314                    config
315                }));
316
317                self
318            }
319
320            /// Registers an action used to configure a particular type of [`Options`](crate::Options) with four dependencies.
321            ///
322            /// # Arguments
323            ///
324            /// * `setup` - The configuration action
325            pub fn post_configure4<F, D1, D2, D3, D4>(self, setup: F) -> Self
326            where
327                F: Fn(&mut T, Svc<D1>, Svc<D2>, Svc<D3>, Svc<D4>) + $($bounds)+,
328                D1: $($bounds)+,
329                D2: $($bounds)+,
330                D3: $($bounds)+,
331                D4: $($bounds)+,
332            {
333                let action = Ref::new(setup);
334                let name = self.name.clone();
335
336                self.services.add(transient_factory(move |sp| {
337                    let config: Ref<dyn PostConfigureOptions<T>> = Ref::new(_Configure4 {
338                        name: name.clone(),
339                        action: action.clone(),
340                        dependency1: sp.get_required::<D1>(),
341                        dependency2: sp.get_required::<D2>(),
342                        dependency3: sp.get_required::<D3>(),
343                        dependency4: sp.get_required::<D4>(),
344                        _marker: PhantomData,
345                    });
346                    config
347                }));
348
349                self
350            }
351
352            /// Registers an action used to configure a particular type of [`Options`](crate::Options) with five dependencies.
353            ///
354            /// # Arguments
355            ///
356            /// * `setup` - The configuration action
357            pub fn post_configure5<F, D1, D2, D3, D4, D5>(self, setup: F) -> Self
358            where
359                F: Fn(&mut T, Svc<D1>, Svc<D2>, Svc<D3>, Svc<D4>, Svc<D5>) + $($bounds)+,
360                D1: $($bounds)+,
361                D2: $($bounds)+,
362                D3: $($bounds)+,
363                D4: $($bounds)+,
364                D5: $($bounds)+,
365            {
366                let action = Ref::new(setup);
367                let name = self.name.clone();
368
369                self.services.add(transient_factory(move |sp| {
370                    let config: Ref<dyn PostConfigureOptions<T>> = Ref::new(_Configure5 {
371                        name: name.clone(),
372                        action: action.clone(),
373                        dependency1: sp.get_required::<D1>(),
374                        dependency2: sp.get_required::<D2>(),
375                        dependency3: sp.get_required::<D3>(),
376                        dependency4: sp.get_required::<D4>(),
377                        dependency5: sp.get_required::<D5>(),
378                        _marker: PhantomData,
379                    });
380                    config
381                }));
382
383                self
384            }
385
386            /// Registers an action used to validate a particular type of [`Options`](crate::Options).
387            ///
388            /// # Arguments
389            ///
390            /// * `action` - The validation action
391            /// * `failure_message` - The message used when validation fails
392            pub fn validate<F, M>(self, action: F, failure_message: M) -> Self
393            where
394                F: Fn(&T) -> bool + $($bounds)+,
395                M: AsRef<str>,
396            {
397                let action = Ref::new(action);
398                let name = self.name.clone();
399                let failure_message = message_or_default(failure_message);
400
401                self.services.add(transient_factory(move |_| {
402                    let validate: Ref<dyn ValidateOptions<T>> = Ref::new(_Validate {
403                        name: name.clone(),
404                        action: action.clone(),
405                        failure_message: failure_message.clone(),
406                        _marker: PhantomData,
407                    });
408                    validate
409                }));
410
411                self
412            }
413
414            /// Registers an action used to validate a particular type of [`Options`](crate::Options) with a single dependency.
415            ///
416            /// # Arguments
417            ///
418            /// * `action` - The validation action
419            /// * `failure_message` - The message used when validation fails
420            pub fn validate1<F, M, D>(self, action: F, failure_message: M) -> Self
421            where
422                F: Fn(&T, Svc<D>) -> bool + $($bounds)+,
423                M: AsRef<str>,
424                D: $($bounds)+,
425            {
426                let action = Ref::new(action);
427                let name = self.name.clone();
428                let failure_message = message_or_default(failure_message);
429
430                self.services.add(transient_factory(move |sp| {
431                    let validate: Ref<dyn ValidateOptions<T>> = Ref::new(_Validate1 {
432                        name: name.clone(),
433                        action: action.clone(),
434                        failure_message: failure_message.clone(),
435                        dependency: sp.get_required::<D>(),
436                        _marker: PhantomData,
437                    });
438                    validate
439                }));
440
441                self
442            }
443
444            /// Registers an action used to validate a particular type of [`Options`](crate::Options) with two dependencies.
445            ///
446            /// # Arguments
447            ///
448            /// * `action` - The validation action
449            /// * `failure_message` - The message used when validation fails
450            pub fn validate2<F, M, D1, D2>(self, action: F, failure_message: M) -> Self
451            where
452                F: Fn(&T, Svc<D1>, Svc<D2>) -> bool + $($bounds)+,
453                M: AsRef<str>,
454                D1: $($bounds)+,
455                D2: $($bounds)+,
456            {
457                let action = Ref::new(action);
458                let name = self.name.clone();
459                let failure_message = message_or_default(failure_message);
460
461                self.services.add(transient_factory(move |sp| {
462                    let validate: Ref<dyn ValidateOptions<T>> = Ref::new(_Validate2 {
463                        name: name.clone(),
464                        action: action.clone(),
465                        failure_message: failure_message.clone(),
466                        dependency1: sp.get_required::<D1>(),
467                        dependency2: sp.get_required::<D2>(),
468                        _marker: PhantomData,
469                    });
470                    validate
471                }));
472
473                self
474            }
475
476            /// Registers an action used to validate a particular type of [`Options`](crate::Options) with three dependencies.
477            ///
478            /// # Arguments
479            ///
480            /// * `action` - The validation action
481            /// * `failure_message` - The message used when validation fails
482            pub fn validate3<F, M, D1, D2, D3>(self, action: F, failure_message: M) -> Self
483            where
484                F: Fn(&T, Svc<D1>, Svc<D2>, Svc<D3>) -> bool + $($bounds)+,
485                M: AsRef<str>,
486                D1: $($bounds)+,
487                D2: $($bounds)+,
488                D3: $($bounds)+,
489            {
490                let action = Ref::new(action);
491                let name = self.name.clone();
492                let failure_message = message_or_default(failure_message);
493
494                self.services.add(transient_factory(move |sp| {
495                    let validate: Ref<dyn ValidateOptions<T>> = Ref::new(_Validate3 {
496                        name: name.clone(),
497                        action: action.clone(),
498                        failure_message: failure_message.clone(),
499                        dependency1: sp.get_required::<D1>(),
500                        dependency2: sp.get_required::<D2>(),
501                        dependency3: sp.get_required::<D3>(),
502                        _marker: PhantomData,
503                    });
504                    validate
505                }));
506
507                self
508            }
509
510            /// Registers an action used to validate a particular type of [`Options`](crate::Options) with four dependencies.
511            ///
512            /// # Arguments
513            ///
514            /// * `action` - The validation action
515            /// * `failure_message` - The message used when validation fails
516            pub fn validate4<F, M, D1, D2, D3, D4>(self, action: F, failure_message: M) -> Self
517            where
518                F: Fn(&T, Svc<D1>, Svc<D2>, Svc<D3>, Svc<D4>) -> bool + $($bounds)+,
519                M: AsRef<str>,
520                D1: $($bounds)+,
521                D2: $($bounds)+,
522                D3: $($bounds)+,
523                D4: $($bounds)+,
524            {
525                let action = Ref::new(action);
526                let name = self.name.clone();
527                let failure_message = message_or_default(failure_message);
528
529                self.services.add(transient_factory(move |sp| {
530                    let validate: Ref<dyn ValidateOptions<T>> = Ref::new(_Validate4 {
531                        name: name.clone(),
532                        action: action.clone(),
533                        failure_message: failure_message.clone(),
534                        dependency1: sp.get_required::<D1>(),
535                        dependency2: sp.get_required::<D2>(),
536                        dependency3: sp.get_required::<D3>(),
537                        dependency4: sp.get_required::<D4>(),
538                        _marker: PhantomData,
539                    });
540                    validate
541                }));
542
543                self
544            }
545
546            /// Registers an action used to validate a particular type of [`Options`](crate::Options) with five dependencies.
547            ///
548            /// # Arguments
549            ///
550            /// * `action` - The validation action
551            /// * `failure_message` - The message used when validation fails
552            pub fn validate5<F, M, D1, D2, D3, D4, D5>(self, action: F, failure_message: M) -> Self
553            where
554                F: Fn(&T, Svc<D1>, Svc<D2>, Svc<D3>, Svc<D4>, Svc<D5>) -> bool + $($bounds)+,
555                M: AsRef<str>,
556                D1: $($bounds)+,
557                D2: $($bounds)+,
558                D3: $($bounds)+,
559                D4: $($bounds)+,
560                D5: $($bounds)+,
561            {
562                let action = Ref::new(action);
563                let name = self.name.clone();
564                let failure_message = message_or_default(failure_message);
565
566                self.services.add(transient_factory(move |sp| {
567                    let validate: Ref<dyn ValidateOptions<T>> = Ref::new(_Validate5 {
568                        name: name.clone(),
569                        action: action.clone(),
570                        failure_message: failure_message.clone(),
571                        dependency1: sp.get_required::<D1>(),
572                        dependency2: sp.get_required::<D2>(),
573                        dependency3: sp.get_required::<D3>(),
574                        dependency4: sp.get_required::<D4>(),
575                        dependency5: sp.get_required::<D5>(),
576                        _marker: PhantomData,
577                    });
578                    validate
579                }));
580
581                self
582            }
583        }
584    }
585}
586
587impl<'a, T> From<OptionsBuilder<'a, T>> for &'a mut ServiceCollection {
588    #[inline]
589    fn from(builder: OptionsBuilder<'a, T>) -> Self {
590        builder.services
591    }
592}
593
594impl<'a, T> Deref for OptionsBuilder<'a, T> {
595    type Target = ServiceCollection;
596
597    #[inline]
598    fn deref(&self) -> &Self::Target {
599        self.services
600    }
601}
602
603impl<'a, T> DerefMut for OptionsBuilder<'a, T> {
604    #[inline]
605    fn deref_mut(&mut self) -> &mut Self::Target {
606        self.services
607    }
608}
609
610fn names_equal(name: Option<&str>, other_name: Option<&str>) -> bool {
611    let matches_all = name.is_none();
612
613    if matches_all || name == other_name {
614        return true;
615    } else if other_name.is_none() {
616        return false;
617    }
618
619    let name1 = name.unwrap();
620    let name2 = other_name.unwrap();
621
622    (name1.len() == name2.len())
623        && ((name1.to_uppercase() == name2.to_uppercase()) || (name1.to_lowercase() == name2.to_lowercase()))
624}
625
626fn message_or_default<T: AsRef<str>>(message: T) -> String {
627    let msg = message.as_ref();
628
629    if msg.is_empty() {
630        String::from("A validation error has occurred.")
631    } else {
632        String::from(msg)
633    }
634}
635
636macro_rules! builder_impl {
637    (($($bounds:tt)+)) => {
638        struct _Configure<TOptions, TAction> {
639            name: Option<String>,
640            action: TAction,
641            _marker: PhantomData<TOptions>,
642        }
643
644        impl<TOptions, TAction> ConfigureOptions<TOptions> for _Configure<TOptions, TAction>
645        where
646            TOptions: Value,
647            TAction: Fn(&mut TOptions) + $($bounds)+,
648        {
649            fn configure(&self, name: Option<&str>, options: &mut TOptions) {
650                if names_equal(self.name.as_deref(), name) {
651                    (self.action)(options)
652                }
653            }
654        }
655
656        impl<TOptions, TAction> PostConfigureOptions<TOptions> for _Configure<TOptions, TAction>
657        where
658            TOptions: Value,
659            TAction: Fn(&mut TOptions) + $($bounds)+,
660        {
661            fn post_configure(&self, name: Option<&str>, options: &mut TOptions) {
662                if names_equal(self.name.as_deref(), name) {
663                    (self.action)(options)
664                }
665            }
666        }
667
668        struct _Configure1<TOptions, TAction, TDep> {
669            name: Option<String>,
670            action: Ref<TAction>,
671            dependency: Svc<TDep>,
672            _marker: PhantomData<TOptions>,
673        }
674
675        impl<TOptions, TAction, TDep> ConfigureOptions<TOptions> for _Configure1<TOptions, TAction, TDep>
676        where
677            TOptions: Value,
678            TAction: Fn(&mut TOptions, Svc<TDep>) + $($bounds)+,
679            TDep: Value,
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
688        impl<TOptions, TAction, TDep> PostConfigureOptions<TOptions>
689            for _Configure1<TOptions, TAction, TDep>
690        where
691            TOptions: Value,
692            TAction: Fn(&mut TOptions, Svc<TDep>) + $($bounds)+,
693            TDep: Value,
694        {
695            fn post_configure(&self, name: Option<&str>, options: &mut TOptions) {
696                if names_equal(self.name.as_deref(), name) {
697                    (self.action)(options, self.dependency.clone())
698                }
699            }
700        }
701
702        struct _Configure2<TOptions, TAction, TDep1, TDep2> {
703            name: Option<String>,
704            action: Ref<TAction>,
705            dependency1: Svc<TDep1>,
706            dependency2: Svc<TDep2>,
707            _marker: PhantomData<TOptions>,
708        }
709
710        impl<TOptions, TAction, TDep1, TDep2> ConfigureOptions<TOptions>
711            for _Configure2<TOptions, TAction, TDep1, TDep2>
712        where
713            TOptions: Value,
714            TAction: Fn(&mut TOptions, Svc<TDep1>, Svc<TDep2>) + $($bounds)+,
715            TDep1: Value,
716            TDep2: Value,
717        {
718            fn configure(&self, name: Option<&str>, options: &mut TOptions) {
719                if names_equal(self.name.as_deref(), name) {
720                    (self.action)(options, self.dependency1.clone(), self.dependency2.clone())
721                }
722            }
723        }
724
725        impl<TOptions, TAction, TDep1, TDep2> PostConfigureOptions<TOptions>
726            for _Configure2<TOptions, TAction, TDep1, TDep2>
727        where
728            TOptions: Value,
729            TAction: Fn(&mut TOptions, Svc<TDep1>, Svc<TDep2>) + $($bounds)+,
730            TDep1: Value,
731            TDep2: Value,
732        {
733            fn post_configure(&self, name: Option<&str>, options: &mut TOptions) {
734                if names_equal(self.name.as_deref(), name) {
735                    (self.action)(options, self.dependency1.clone(), self.dependency2.clone())
736                }
737            }
738        }
739
740        struct _Configure3<TOptions, TAction, TDep1, TDep2, TDep3> {
741            name: Option<String>,
742            action: Ref<TAction>,
743            dependency1: Svc<TDep1>,
744            dependency2: Svc<TDep2>,
745            dependency3: Svc<TDep3>,
746            _marker: PhantomData<TOptions>,
747        }
748
749        impl<TOptions, TAction, TDep1, TDep2, TDep3> ConfigureOptions<TOptions>
750            for _Configure3<TOptions, TAction, TDep1, TDep2, TDep3>
751        where
752            TOptions: Value,
753            TAction: Fn(&mut TOptions, Svc<TDep1>, Svc<TDep2>, Svc<TDep3>) + $($bounds)+,
754            TDep1: Value,
755            TDep2: Value,
756            TDep3: Value,
757        {
758            fn configure(&self, name: Option<&str>, options: &mut TOptions) {
759                if names_equal(self.name.as_deref(), name) {
760                    (self.action)(
761                        options,
762                        self.dependency1.clone(),
763                        self.dependency2.clone(),
764                        self.dependency3.clone(),
765                    )
766                }
767            }
768        }
769
770        impl<TOptions, TAction, TDep1, TDep2, TDep3> PostConfigureOptions<TOptions>
771            for _Configure3<TOptions, TAction, TDep1, TDep2, TDep3>
772        where
773            TOptions: Value,
774            TAction: Fn(&mut TOptions, Svc<TDep1>, Svc<TDep2>, Svc<TDep3>) + $($bounds)+,
775            TDep1: Value,
776            TDep2: Value,
777            TDep3: Value,
778        {
779            fn post_configure(&self, name: Option<&str>, options: &mut TOptions) {
780                if names_equal(self.name.as_deref(), name) {
781                    (self.action)(
782                        options,
783                        self.dependency1.clone(),
784                        self.dependency2.clone(),
785                        self.dependency3.clone(),
786                    )
787                }
788            }
789        }
790
791        struct _Configure4<TOptions, TAction, TDep1, TDep2, TDep3, TDep4> {
792            name: Option<String>,
793            action: Ref<TAction>,
794            dependency1: Svc<TDep1>,
795            dependency2: Svc<TDep2>,
796            dependency3: Svc<TDep3>,
797            dependency4: Svc<TDep4>,
798            _marker: PhantomData<TOptions>,
799        }
800
801        impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4> ConfigureOptions<TOptions>
802            for _Configure4<TOptions, TAction, TDep1, TDep2, TDep3, TDep4>
803        where
804            TOptions: Value,
805            TAction: Fn(&mut TOptions, Svc<TDep1>, Svc<TDep2>, Svc<TDep3>, Svc<TDep4>) + $($bounds)+,
806            TDep1: Value,
807            TDep2: Value,
808            TDep3: Value,
809            TDep4: Value,
810        {
811            fn 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                        self.dependency4.clone(),
819                    )
820                }
821            }
822        }
823
824        impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4> PostConfigureOptions<TOptions>
825            for _Configure4<TOptions, TAction, TDep1, TDep2, TDep3, TDep4>
826        where
827            TOptions: Value,
828            TAction: Fn(&mut TOptions, Svc<TDep1>, Svc<TDep2>, Svc<TDep3>, Svc<TDep4>) + $($bounds)+,
829            TDep1: Value,
830            TDep2: Value,
831            TDep3: Value,
832            TDep4: Value,
833        {
834            fn post_configure(&self, name: Option<&str>, options: &mut TOptions) {
835                if names_equal(self.name.as_deref(), name) {
836                    (self.action)(
837                        options,
838                        self.dependency1.clone(),
839                        self.dependency2.clone(),
840                        self.dependency3.clone(),
841                        self.dependency4.clone(),
842                    )
843                }
844            }
845        }
846
847        struct _Configure5<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5> {
848            name: Option<String>,
849            action: Ref<TAction>,
850            dependency1: Svc<TDep1>,
851            dependency2: Svc<TDep2>,
852            dependency3: Svc<TDep3>,
853            dependency4: Svc<TDep4>,
854            dependency5: Svc<TDep5>,
855            _marker: PhantomData<TOptions>,
856        }
857
858        impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5> ConfigureOptions<TOptions>
859            for _Configure5<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5>
860        where
861            TOptions: Value,
862            TAction: Fn(&mut TOptions, Svc<TDep1>, Svc<TDep2>, Svc<TDep3>, Svc<TDep4>, Svc<TDep5>) + $($bounds)+,
863            TDep1: Value,
864            TDep2: Value,
865            TDep3: Value,
866            TDep4: Value,
867            TDep5: Value,
868        {
869            fn configure(&self, name: Option<&str>, options: &mut TOptions) {
870                if names_equal(self.name.as_deref(), name) {
871                    (self.action)(
872                        options,
873                        self.dependency1.clone(),
874                        self.dependency2.clone(),
875                        self.dependency3.clone(),
876                        self.dependency4.clone(),
877                        self.dependency5.clone(),
878                    )
879                }
880            }
881        }
882
883        impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5> PostConfigureOptions<TOptions>
884            for _Configure5<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5>
885        where
886            TOptions: Value,
887            TAction: Fn(&mut TOptions, Svc<TDep1>, Svc<TDep2>, Svc<TDep3>, Svc<TDep4>, Svc<TDep5>) + $($bounds)+,
888            TDep1: Value,
889            TDep2: Value,
890            TDep3: Value,
891            TDep4: Value,
892            TDep5: Value,
893        {
894            fn post_configure(&self, name: Option<&str>, options: &mut TOptions) {
895                if names_equal(self.name.as_deref(), name) {
896                    (self.action)(
897                        options,
898                        self.dependency1.clone(),
899                        self.dependency2.clone(),
900                        self.dependency3.clone(),
901                        self.dependency4.clone(),
902                        self.dependency5.clone(),
903                    )
904                }
905            }
906        }
907
908        struct _Validate<TOptions, TAction> {
909            name: Option<String>,
910            action: Ref<TAction>,
911            failure_message: String,
912            _marker: PhantomData<TOptions>,
913        }
914
915        impl<TOptions, TAction> ValidateOptions<TOptions> for _Validate<TOptions, TAction>
916        where
917            TOptions: Value,
918            TAction: Fn(&TOptions) -> bool + $($bounds)+,
919        {
920            fn validate(&self, name: Option<&str>, options: &TOptions) -> ValidateOptionsResult {
921                if names_equal(self.name.as_deref(), name) {
922                    if (self.action)(options) {
923                        return ValidateOptionsResult::success();
924                    } else {
925                        return ValidateOptionsResult::fail(&self.failure_message);
926                    }
927                }
928
929                return ValidateOptionsResult::skip();
930            }
931        }
932
933        struct _Validate1<TOptions, TAction, TDep> {
934            name: Option<String>,
935            action: Ref<TAction>,
936            failure_message: String,
937            dependency: Svc<TDep>,
938            _marker: PhantomData<TOptions>,
939        }
940
941        impl<TOptions, TAction, TDep> ValidateOptions<TOptions> for _Validate1<TOptions, TAction, TDep>
942        where
943            TOptions: Value,
944            TAction: Fn(&TOptions, Svc<TDep>) -> bool + $($bounds)+,
945            TDep: Value,
946        {
947            fn validate(&self, name: Option<&str>, options: &TOptions) -> ValidateOptionsResult {
948                if names_equal(self.name.as_deref(), name) {
949                    if (self.action)(options, self.dependency.clone()) {
950                        return ValidateOptionsResult::success();
951                    } else {
952                        return ValidateOptionsResult::fail(&self.failure_message);
953                    }
954                }
955
956                return ValidateOptionsResult::skip();
957            }
958        }
959
960        struct _Validate2<TOptions, TAction, TDep1, TDep2> {
961            name: Option<String>,
962            action: Ref<TAction>,
963            failure_message: String,
964            dependency1: Svc<TDep1>,
965            dependency2: Svc<TDep2>,
966            _marker: PhantomData<TOptions>,
967        }
968
969        impl<TOptions, TAction, TDep1, TDep2> ValidateOptions<TOptions>
970            for _Validate2<TOptions, TAction, TDep1, TDep2>
971        where
972            TOptions: Value,
973            TAction: Fn(&TOptions, Svc<TDep1>, Svc<TDep2>) -> bool + $($bounds)+,
974            TDep1: Value,
975            TDep2: Value,
976        {
977            fn validate(&self, name: Option<&str>, options: &TOptions) -> ValidateOptionsResult {
978                if names_equal(self.name.as_deref(), name) {
979                    if (self.action)(options, self.dependency1.clone(), self.dependency2.clone()) {
980                        return ValidateOptionsResult::success();
981                    } else {
982                        return ValidateOptionsResult::fail(&self.failure_message);
983                    }
984                }
985
986                return ValidateOptionsResult::skip();
987            }
988        }
989
990        struct _Validate3<TOptions, TAction, TDep1, TDep2, TDep3> {
991            name: Option<String>,
992            action: Ref<TAction>,
993            failure_message: String,
994            dependency1: Svc<TDep1>,
995            dependency2: Svc<TDep2>,
996            dependency3: Svc<TDep3>,
997            _marker: PhantomData<TOptions>,
998        }
999
1000        impl<TOptions, TAction, TDep1, TDep2, TDep3> ValidateOptions<TOptions>
1001            for _Validate3<TOptions, TAction, TDep1, TDep2, TDep3>
1002        where
1003            TOptions: Value,
1004            TAction: Fn(&TOptions, Svc<TDep1>, Svc<TDep2>, Svc<TDep3>) -> bool + $($bounds)+,
1005            TDep1: Value,
1006            TDep2: Value,
1007            TDep3: Value,
1008        {
1009            fn validate(&self, name: Option<&str>, options: &TOptions) -> ValidateOptionsResult {
1010                if names_equal(self.name.as_deref(), name) {
1011                    if (self.action)(
1012                        options,
1013                        self.dependency1.clone(),
1014                        self.dependency2.clone(),
1015                        self.dependency3.clone(),
1016                    ) {
1017                        return ValidateOptionsResult::success();
1018                    } else {
1019                        return ValidateOptionsResult::fail(&self.failure_message);
1020                    }
1021                }
1022
1023                return ValidateOptionsResult::skip();
1024            }
1025        }
1026
1027        struct _Validate4<TOptions, TAction, TDep1, TDep2, TDep3, TDep4> {
1028            name: Option<String>,
1029            action: Ref<TAction>,
1030            failure_message: String,
1031            dependency1: Svc<TDep1>,
1032            dependency2: Svc<TDep2>,
1033            dependency3: Svc<TDep3>,
1034            dependency4: Svc<TDep4>,
1035            _marker: PhantomData<TOptions>,
1036        }
1037
1038        impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4> ValidateOptions<TOptions>
1039            for _Validate4<TOptions, TAction, TDep1, TDep2, TDep3, TDep4>
1040        where
1041            TOptions: Value,
1042            TAction: Fn(&TOptions, Ref<TDep1>, Ref<TDep2>, Ref<TDep3>, Ref<TDep4>) -> bool + $($bounds)+,
1043            TDep1: Value,
1044            TDep2: Value,
1045            TDep3: Value,
1046            TDep4: Value,
1047        {
1048            fn validate(&self, name: Option<&str>, options: &TOptions) -> ValidateOptionsResult {
1049                if names_equal(self.name.as_deref(), name) {
1050                    if (self.action)(
1051                        options,
1052                        self.dependency1.clone(),
1053                        self.dependency2.clone(),
1054                        self.dependency3.clone(),
1055                        self.dependency4.clone(),
1056                    ) {
1057                        return ValidateOptionsResult::success();
1058                    } else {
1059                        return ValidateOptionsResult::fail(&self.failure_message);
1060                    }
1061                }
1062
1063                return ValidateOptionsResult::skip();
1064            }
1065        }
1066
1067        struct _Validate5<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5> {
1068            name: Option<String>,
1069            action: Ref<TAction>,
1070            failure_message: String,
1071            dependency1: Svc<TDep1>,
1072            dependency2: Svc<TDep2>,
1073            dependency3: Svc<TDep3>,
1074            dependency4: Svc<TDep4>,
1075            dependency5: Svc<TDep5>,
1076            _marker: PhantomData<TOptions>,
1077        }
1078
1079        impl<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5> ValidateOptions<TOptions>
1080            for _Validate5<TOptions, TAction, TDep1, TDep2, TDep3, TDep4, TDep5>
1081        where
1082            TOptions: Value,
1083            TAction: Fn(&TOptions, Svc<TDep1>, Svc<TDep2>, Svc<TDep3>, Svc<TDep4>, Svc<TDep5>) -> bool + $($bounds)+,
1084            TDep1: Value,
1085            TDep2: Value,
1086            TDep3: Value,
1087            TDep4: Value,
1088            TDep5: Value,
1089        {
1090            fn validate(&self, name: Option<&str>, options: &TOptions) -> ValidateOptionsResult {
1091                if names_equal(self.name.as_deref(), name) {
1092                    if (self.action)(
1093                        options,
1094                        self.dependency1.clone(),
1095                        self.dependency2.clone(),
1096                        self.dependency3.clone(),
1097                        self.dependency4.clone(),
1098                        self.dependency5.clone(),
1099                    ) {
1100                        return ValidateOptionsResult::success();
1101                    } else {
1102                        return ValidateOptionsResult::fail(&self.failure_message);
1103                    }
1104                }
1105
1106                return ValidateOptionsResult::skip();
1107            }
1108        }
1109    }
1110}
1111
1112cfg_if! {
1113    if #[cfg(feature = "async")] {
1114        builder!((Send + Sync + 'static));
1115        builder_impl!((Send + Sync + 'static));
1116    } else {
1117        builder!(('static));
1118        builder_impl!(('static));
1119    }
1120}