use crate::{EndpointToggle, Interval, Intervals, LeftT};
pub trait InIntervalsMap: Sized {
type Endpoint;
fn map<F>(self, fun: F) -> IntervalsMap<Self, F>;
}
impl<I> InIntervalsMap for I
where
I: Intervals + Sized,
I::Endpoint: Clone + EndpointToggle,
{
type Endpoint = <I as Intervals>::Endpoint;
fn map<F>(self, fun: F) -> IntervalsMap<Self, F>
where
Self: Sized,
{
IntervalsMap { it: self, fun }
}
}
pub struct IntervalsMap<It, F> {
it: It,
fun: F,
}
impl<It, F, Out> Intervals for IntervalsMap<It, F>
where
It: Intervals,
It::Endpoint: Clone,
F: Fn(&It::Value) -> Out,
It::Value: Copy,
{
type Endpoint = It::Endpoint;
type Value = Out;
fn head(
&mut self,
pos: Option<LeftT<Self::Endpoint>>,
) -> Option<Interval<Self::Endpoint, Out>> {
let v = self.it.head(pos);
match v {
Some(i) => Some(Interval::new_lr(
i.left(),
i.right(),
(self.fun)(&i.value()),
)),
None => None,
}
}
}