use std::marker::PhantomData;
use crate::Decorator;
pub struct Builder<T> {
value: T,
}
pub struct OrderedBuild<T> {
value: T,
}
impl<T> Builder<T> {
pub fn new(initial: T) -> Self {
Builder { value: initial }
}
pub fn step<O>(self, mut decorator: impl Decorator<T, O>) -> Step<O> {
Step {
cur: decorator.produce(self.value),
}
}
}
impl<T> OrderedBuild<T> {
pub fn new(initial: T) -> Self {
Self { value: initial }
}
pub fn step<O, D>(self, mut decorator: D) -> GuardedStep<O, D>
where
D: Decorator<T, O>,
{
GuardedStep {
cur: decorator.produce(self.value),
phantom: PhantomData,
}
}
}
#[must_use = "Steps do nothing unless you continue the chain or call .build()"]
pub struct Step<T> {
pub(crate) cur: T,
}
impl<T> Step<T> {
pub fn step<O>(self, mut decorator: impl Decorator<T, O>) -> Step<O> {
Step {
cur: decorator.produce(self.cur),
}
}
pub fn build(self) -> T {
self.cur
}
}
pub trait FromStep<T> {}
pub trait AnyStep {}
impl<D, T> FromStep<D> for T where T: AnyStep {}
pub struct GuardedStep<T, D> {
cur: T,
phantom: PhantomData<D>, }
impl<T, D> GuardedStep<T, D> {
pub fn step<O, NewD>(self, mut decortor: NewD) -> GuardedStep<O, NewD>
where
Self: Sized,
NewD: Decorator<T, O> + FromStep<Self>,
{
GuardedStep {
cur: decortor.produce(self.cur),
phantom: PhantomData,
}
}
pub fn build(self) -> T {
self.cur
}
}