# odsek
[](https://crates.io/crates/odsek)
[](https://docs.rs/odsek)
[](https://github.com/ra1u/odsek/actions/workflows/ci.yml)
[](#license)
[](#minimum-supported-rust-version)
Lazy, pull-based composition of mathematical interval sets — `no_std`-compatible, allocation-free.
An `Intervals` is an ordered, non-overlapping set of `Interval`s. 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 `Vec`s.
## 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
```rust
use odsek::*;
let ia = Interval::new(EndpointOC::Closed(1), EndpointOC::Closed(3), "A");
let ib = Interval::new(EndpointOC::Open(2), EndpointOC::Open(4), "B");
let isa = IntervalsSingle::new(ia);
let isb = IntervalsSingle::new(ib);
// (2, 3] with value ("A", "B")
let intersection = (isa & isb).into_iter().collect::<Vec<_>>();
assert_eq!(
intersection,
vec![Interval::new(
EndpointOC::Open(2),
EndpointOC::Closed(3),
("A", "B"),
)],
);
let left = IntervalsSingle::new(Interval::new(EndpointOC::Closed(1), EndpointOC::Closed(3), "A"));
let right = IntervalsSingle::new(Interval::new(EndpointOC::Open(2), EndpointOC::Open(4), "B"));
// Union preserves which side contributed to each output segment.