odsek
Lazy, pull-based composition of mathematical interval sets — no_std-compatible, allocation-free.
An Intervals is an ordered, non-overlapping set of Intervals. Sets compose via set operations (intersection &, union |) and transforms (map, IntervalShift) without intermediate allocations. Each Interval carries a value, so composition can also be read as joining attributed segments.
When to use this crate
Use odsek when you need to combine ordered interval streams while preserving the data attached to each segment: calendars, availability windows, timeline annotations, numeric domains, or other range-like datasets. It is designed for libraries and embedded/no-heap contexts that want lazy composition instead of building intermediate Vecs.
Features
no_std— no heap allocation in the core API.- Open and closed endpoints (
EndpointOC::{Open, Closed}), or symmetric[a, b)endpoints (EndpointSymmetric). - Pull-based:
head(pos)returns the next interval whose right endpoint is> pos. Random-access friendly. - Composable:
&(intersection) yields tupled values,|(union) yields(Option<A>, Option<B>). - Built-in combinators:
IntervalsSingle,IntervalsFromArray,IntervalShift,IntervalsCache,IntervalsMap.
Example
use *;
let ia = new;
let ib = new;
let isa = new;
let isb = new;
// (2, 3] with value ("A", "B")
let intersection = .into_iter.;
assert_eq!;
let left = new;
let right = new;
// Union preserves which side contributed to each output segment.
let union = .into_iter.;
assert_eq!;
More examples in examples/: intersection.rs, union.rs, shift.rs. Run with cargo run --example intersection.
Endpoint semantics
EndpointOC::Closed(x) includes x; EndpointOC::Open(x) excludes it. When a boundary is reused as the end of one segment and the start of another, the crate toggles open/closed status so adjacent output intervals do not double-count the same boundary. EndpointSymmetric(x) is simpler: left endpoints are treated as closed and right endpoints as open, so intervals follow the standard [a, b) convention.
Feature flags
operators(default) — enables the&/|operator overloads. Disable with--no-default-featuresto use the explicitand(a, b)/or(a, b)free functions instead.
no_std
The crate is #![no_std] outside of tests. Tests opt back into std for the convenience of Vec and println!.
Minimum Supported Rust Version
Rust 1.70.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.