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