1use crate::*;
2
3#[cfg_attr(feature = "async", maybe_impl::traits(Send, Sync))]
5pub trait OptionsFactory<T: Value> {
6 fn create(&self, name: Option<&str>) -> Result<T, ValidateOptionsResult>;
12}
13
14#[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 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}