use crate::errors::Result;
use crate::{
utils::{FromStep, StepIndex, StepIndexBase},
Collector, Decorator,
};
use std::marker::PhantomData;
#[doc(hidden)]
pub struct FirstStep<T>(pub(crate) T);
impl<T> Collector<T> for FirstStep<T> {
fn collect(self) -> Result<T> {
Ok(self.0)
}
}
#[must_use = "Steps do nothing unless you consume (collect) them"]
pub struct Step<D, P, T, ID> {
pub(crate) decorator: D,
pub(crate) previous: P,
pub(crate) _previous_type: PhantomData<T>,
pub(crate) _index: ID,
}
impl<D, P, T, ID> Step<D, P, T, ID> {
pub fn step<NewD, T1, T2>(self, decorator: NewD) -> Step<NewD, Self, T1, StepIndex<ID>>
where
NewD: Decorator<T1, T2>,
D: Decorator<T, T1>,
{
Step {
decorator,
previous: self,
_previous_type: PhantomData,
_index: StepIndex(PhantomData),
}
}
pub fn get_index(&self) -> usize
where
ID: StepIndexBase,
{
ID::ID
}
}
impl<D, P, T, ID, O> Collector<O> for Step<D, P, T, ID>
where
D: Decorator<T, O>,
P: Collector<T>,
{
fn collect(mut self) -> Result<O> {
self.decorator.produce(self.previous.collect()?)
}
}
pub struct GuardedStep<D, P, T, ID> {
pub(crate) decorator: D,
pub(crate) previous: P,
pub(crate) _previous_type: PhantomData<T>,
pub(crate) _index: ID,
}
impl<D, P, T, ID> GuardedStep<D, P, T, ID> {
pub fn step<NewD, T1, T2>(self, decorator: NewD) -> GuardedStep<NewD, Self, T1, StepIndex<ID>>
where
NewD: Decorator<T1, T2> + FromStep<D>,
D: Decorator<T, T1>,
{
GuardedStep {
decorator,
previous: self,
_previous_type: PhantomData,
_index: StepIndex(PhantomData),
}
}
pub fn get_index(&self) -> usize
where
ID: StepIndexBase,
{
ID::ID
}
}
impl<D, P, T, ID, O> Collector<O> for GuardedStep<D, P, T, ID>
where
D: Decorator<T, O>,
P: Collector<T>,
{
fn collect(mut self) -> Result<O> {
self.decorator.produce(self.previous.collect()?)
}
}