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
22impl<T: Value + Default> DefaultOptionsFactory<T> {
23 pub fn new(
31 configurations: Vec<Ref<dyn ConfigureOptions<T>>>,
32 post_configurations: Vec<Ref<dyn PostConfigureOptions<T>>>,
33 validations: Vec<Ref<dyn ValidateOptions<T>>>,
34 ) -> Self {
35 Self {
36 configurations,
37 post_configurations,
38 validations,
39 }
40 }
41}
42
43impl<T: Value + Default> OptionsFactory<T> for DefaultOptionsFactory<T> {
44 fn create(&self, name: Option<&str>) -> Result<T, ValidateOptionsResult> {
45 let mut options = Default::default();
46
47 for configuration in &self.configurations {
48 configuration.configure(name, &mut options);
49 }
50
51 for configuration in &self.post_configurations {
52 configuration.post_configure(name, &mut options);
53 }
54
55 if !self.validations.is_empty() {
56 let mut failures = Vec::new();
57
58 for validation in &self.validations {
59 let result = validation.validate(name, &options);
60
61 if result.failed() {
62 failures.extend_from_slice(result.failures())
63 }
64 }
65
66 if !failures.is_empty() {
67 return Err(ValidateOptionsResult::fail_many(failures.iter()));
68 }
69 }
70
71 Ok(options)
72 }
73}