use crate::traits::GenType;
pub struct Reader<'a, R, A>
where
R: Clone,
{
pub(crate) run_reader: Option<Box<dyn FnOnce(R) -> A + 'a>>,
}
impl<'a, R, A> Reader<'a, R, A>
where
R: Clone,
{
pub fn get() -> Reader<'a, R, R> {
Reader::<'a, R, R> {
run_reader: Some(Box::new(|r: R| r)),
}
}
pub fn new<F>(f: F) -> Self
where
F: FnOnce(R) -> A + 'a,
{
Self {
run_reader: Some(Box::new(f)),
}
}
pub fn run(self, r: R) -> A {
self.run_reader
.map(move |f| f(r))
.expect("Reader has inner func")
}
}
impl<'a, RA, A> Reader<'a, RA, A>
where
RA: Clone + 'a,
A: 'a,
{
pub fn modify<F, RB>(self, f: F) -> Reader<'a, RB, A>
where
F: FnOnce(RB) -> RA + 'a,
RB: Clone,
{
Reader::<'a, RB, A> {
run_reader: Some(Box::new(move |rt: RB| -> A { self.run(f(rt)) })),
}
}
}
impl<'a, R, A> GenType for Reader<'a, R, A>
where
R: Clone,
{
type Type<B> = Reader<'a, R, B>;
}