odsek 0.1.0

Lazy, pull-based composition of mathematical interval sets with open/closed endpoints, no_std-compatible.
Documentation
use crate::interval::*;

/// An ordered, non-overlapping stream of intervals queried by position.
///
/// Implementors expose a single pull-based method, [`head`](Self::head), that
/// returns the next interval whose right endpoint is strictly greater than
/// `pos`. Iteration is layered on top by repeatedly calling `head` with the
/// previous interval's right endpoint converted to a left position via
/// [`RightT::into_left`].
///
/// `head` is **random-access**: callers may pass any `pos`, not just a
/// monotonically increasing sequence. Implementations should be prepared to
/// jump (see `IntervalsFromArray`'s binary-search implementation).
///
/// # Composition
///
/// `Intervals` values compose through combinators:
///
/// - intersection via [`and`](crate::and) / `&`
/// - union via [`or`](crate::or) / `|`
/// - value transforms via [`InIntervalsMap::map`](crate::InIntervalsMap::map)
/// - endpoint transforms via [`InIntervalsMapEndpoints::map_endpoints`](crate::InIntervalsMapEndpoints::map_endpoints),
///   [`IntervalShift`](crate::IntervalShift), [`IntervalStretch`](crate::IntervalStretch)
/// - memoization via [`IntervalsCache`](crate::IntervalsCache)
pub trait Intervals {
    /// The endpoint flavor — typically [`EndpointOC`](crate::EndpointOC) or
    /// [`EndpointSymmetric`](crate::EndpointSymmetric).
    type Endpoint;
    /// The value attached to each interval.
    type Value;

    /// Return the next interval whose right endpoint is greater than `pos`.
    ///
    /// If `pos` is `None`, returns the very first interval. If no interval
    /// satisfies the condition, returns `None`.
    ///
    /// Implementations must handle arbitrary `pos`, including positions that
    /// jump backward or skip past many intervals.
    fn head(
        &mut self,
        pos: Option<LeftT<Self::Endpoint>>,
    ) -> Option<Interval<Self::Endpoint, Self::Value>>;
}

/// A passthrough wrapper used as the result type of the [`and`](crate::and)
/// and [`or`](crate::or) free functions.
///
/// Its sole purpose is to give a single named type that the `BitAnd` / `BitOr`
/// operator overloads can be implemented on, avoiding Rust's coherence
/// limitations on blanket impls.
pub struct IntervalsWrap<W> {
    /// The wrapped inner stream.
    wrap: W,
}

impl<W> IntervalsWrap<W> {
    /// Wrap an inner stream.
    pub(crate) fn new(wrap: W) -> IntervalsWrap<W> {
        IntervalsWrap { wrap }
    }

    /// Discard the wrapper and return the inner stream.
    pub fn unwrap(self) -> W {
        self.wrap
    }
}

impl<W> Intervals for IntervalsWrap<W>
where
    W: Intervals,
{
    type Endpoint = W::Endpoint;
    type Value = W::Value;

    fn head(
        &mut self,
        pos: Option<LeftT<Self::Endpoint>>,
    ) -> Option<Interval<Self::Endpoint, Self::Value>> {
        self.wrap.head(pos)
    }
}