1use crate::{
2 validation::{Error, Validate},
3 Configure, PostConfigure, Ref, Value,
4};
5
6#[cfg_attr(feature = "async", maybe_impl::traits(Send, Sync))]
8pub trait Factory<T: Value> {
9 fn create(&self, name: &str) -> Result<T, Error>;
15}
16
17#[derive(Default)]
19pub struct DefaultFactory<T: Value + Default> {
20 configurations: Vec<Ref<dyn Configure<T>>>,
21 post_configurations: Vec<Ref<dyn PostConfigure<T>>>,
22 validations: Vec<Ref<dyn Validate<T>>>,
23}
24
25impl<T: Value + Default> DefaultFactory<T> {
26 pub fn new(
34 configurations: Vec<Ref<dyn Configure<T>>>,
35 post_configurations: Vec<Ref<dyn PostConfigure<T>>>,
36 validations: Vec<Ref<dyn Validate<T>>>,
37 ) -> Self {
38 Self {
39 configurations,
40 post_configurations,
41 validations,
42 }
43 }
44}
45
46impl<T: Value + Default> Factory<T> for DefaultFactory<T> {
47 fn create(&self, name: &str) -> Result<T, Error> {
48 let mut options = Default::default();
49
50 for configuration in &self.configurations {
51 configuration.run(name, &mut options);
52 }
53
54 for configuration in &self.post_configurations {
55 configuration.run(name, &mut options);
56 }
57
58 let mut failures = Vec::new();
59
60 for validation in &self.validations {
61 if let Err(error) = validation.run(name, &options) {
62 failures.extend_from_slice(error.failures());
63 }
64 }
65
66 if failures.is_empty() {
67 Ok(options)
68 } else {
69 Err(Error::many(failures))
70 }
71 }
72}