options/
factory.rs

1use crate::*;
2
3/// Defines the behavior of an object that creates configuration [`Options`](crate::Options).
4#[cfg_attr(feature = "async", maybe_impl::traits(Send, Sync))]
5pub trait OptionsFactory<T: Value> {
6    /// Creates and returns new configuration options.
7    ///
8    /// # Arguments
9    ///
10    /// * `name` - The optional name of the configuration options to create
11    fn create(&self, name: Option<&str>) -> Result<T, ValidateOptionsResult>;
12}
13
14/// Represents the default factory used to create configuration [`Options`](crate::Options).
15#[derive(Default)]
16pub struct DefaultOptionsFactory<T: Value + Default> {
17    configurations: Vec<Ref<dyn ConfigureOptions<T>>>,
18    post_configurations: Vec<Ref<dyn PostConfigureOptions<T>>>,
19    validations: Vec<Ref<dyn ValidateOptions<T>>>,
20}
21
22unsafe impl<T: Send + Sync + Default> Send for DefaultOptionsFactory<T> {}
23unsafe impl<T: Send + Sync + Default> Sync for DefaultOptionsFactory<T> {}
24
25impl<T: Value + Default> DefaultOptionsFactory<T> {
26    /// Initializes a new options factory.
27    ///
28    /// # Arguments
29    ///
30    /// * `configurations` - The configurations used to [configure options](crate::ConfigureOptions).
31    /// * `post_configurations` - The configurations used to [post-configure options](crate::PostConfigureOptions).
32    /// * `validations` - The validations used to [validate options](crate::ValidateOptions).
33    pub fn new(
34        configurations: Vec<Ref<dyn ConfigureOptions<T>>>,
35        post_configurations: Vec<Ref<dyn PostConfigureOptions<T>>>,
36        validations: Vec<Ref<dyn ValidateOptions<T>>>,
37    ) -> Self {
38        Self {
39            configurations,
40            post_configurations,
41            validations,
42        }
43    }
44}
45
46impl<T: Value + Default> OptionsFactory<T> for DefaultOptionsFactory<T> {
47    fn create(&self, name: Option<&str>) -> Result<T, ValidateOptionsResult> {
48        let mut options = Default::default();
49
50        for configuration in &self.configurations {
51            configuration.configure(name, &mut options);
52        }
53
54        for configuration in &self.post_configurations {
55            configuration.post_configure(name, &mut options);
56        }
57
58        if !self.validations.is_empty() {
59            let mut failures = Vec::new();
60
61            for validation in &self.validations {
62                let result = validation.validate(name, &options);
63
64                if result.failed() {
65                    failures.extend_from_slice(result.failures())
66                }
67            }
68
69            if !failures.is_empty() {
70                return Err(ValidateOptionsResult::fail_many(failures.iter()));
71            }
72        }
73
74        Ok(options)
75    }
76}