ruex/foundation/patterns/
builder.rs

1//! Builder Design Pattern
2//!
3//! Builder pattern builds a complex object using simple objects and using a step by step approach. 
4//! This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.
5//!
6//! It is used to construct a complex object step by step and the final step will return the object. 
7//! The process of constructing an object should be generic so that it can be used to 
8//! create different representations of the same object.
9
10use std::cell::RefCell;
11
12use crate::prelude::{Getter, SetterMut, With, WithBuilder};
13
14/// Promote the Getter trait.
15impl<Target, From> Getter<From> for Target
16where
17    From: AsRef<Target>,
18{
19    fn get(from: &From) -> &Target {
20        from.as_ref()
21    }
22}
23
24/// Builder pattern implementation.
25pub struct Builder<T: Default> {
26    /// Contains the builder context
27    pub inner: RefCell<Option<T>>,
28}
29
30impl<T: Default> Default for Builder<T> {
31    fn default() -> Self {
32        Self {
33            inner: RefCell::new(Some(Default::default())),
34        }
35    }
36}
37
38impl<T: Default> Builder<T> {
39    /// Finally creates the entity
40    pub fn build(&self) -> Option<T> {
41        self.inner.borrow_mut().take()
42    }
43}
44
45/// Promote With trait for all objects which implement Setter trait.
46///
47/// Current version of Rust is not supported trait exclusion from trait bounds.
48///
49/// So if you need IMP'ish version of With, you should to implement it yourself
50/// something like a:
51/// `impl With<Title> for Builder<Window>`
52///
53impl<Param, Target> With<Param> for Builder<Target>
54where
55    Target: Default + SetterMut<Param>,
56{
57    fn with(self, param: Param) -> Self {
58        self.inner
59            .borrow_mut()
60            .as_mut()
61            .map(|val| SetterMut::<Param>::set(val, param));
62        self
63    }
64}
65
66/// Promote the WithBuilder trait for all builders which able
67/// to configure specific parameter types.
68impl<Target, Param> WithBuilder<Param> for Target
69where
70    Builder<Target>: With<Param>,
71    Target: Default,
72{
73    fn with(param: Param) -> Builder<Self> {
74        Builder::<Self>::default().with(param)
75    }
76}
77
78// /// Simple method to generate builder of object.
79// pub trait Construction<T> {
80//     fn construct() -> Builder<T>;
81// }
82
83// impl<T> Construction<T> for T
84// where
85//     T: Default + Clone,
86// {
87//     fn construct() -> Builder<T> {
88//         Builder::<T>::default()
89//     }
90// }