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// }