# Rust intervals   [![Build Status]][actions] [![Latest Version]][crates.io] [![Docs Badge]][docs] [Build Status]: https://github.com/briot/rust_intervals/actions/workflows/tests.yml/badge.svg [actions]: https://actions-badge.atrox.dev/briot/rust_intervals/goto [Latest Version]: https://img.shields.io/crates/v/rust_intervals.svg [crates.io]: https://crates.io/crates/rust_intervals [Docs Badge]: https://docs.rs/rust_intervals/badge.svg [docs]: https://docs.rs/rust_intervals This package provides various functions to deal with intervals (aka ranges) of values. ## Features It provides the following features: - **Generic** over the interval type. Support out of the box for u8, u16, u32, u64, i8, i16, i32, i64, char, and optionally for chrono::DateTime - Extensive **testing**, with **coverage** of nearly 100% of the code and basic fuzzing. - Supports any variation on **open-closed**, open-open, closed-open, closed-closed, unbounded-open, unbounded-closed, open-unbounded, and close-unbounded intervals. These intervals can be freely combined. - Usable with types that do not even provide comparison, though with reduce feature set. The more traits your type has, the more functions the interval provides. - Standard queries like * `contains()`: whether the interval contains a specific value * `contains_interval()`: whether the interval fully includes another interval. * `is_empty()`: does the interval contain any value ? * `equivalent()`: do two intervals contain the same set of values ? * `strictly_left_of()`, `left_of()`, `right_of()`, `strictly_right_of()`: relative positions of two intervals * `convex_hull()`: smallest interval that contains two others * `difference()`: all values in one interval but not in another * `symmetric_difference()`: all values in either interval, but not in both * `intersection()`: all values in both intervals * `between()`: all values between two intervals * `contiguous()`: whether two intervals are contiguous, with no values between them * `union()`: union of two contiguous intervals - Operator overloads for the queries above (`&`, `|`, `^`, `==`) - Support for `serde` - Support for `no_std` - Support for standard traits like `Default`, `Clone`, `Copy`, `Display`, `Debug`, `Eq`, `PartialEq`, `Ord`, `PartialOrd`, `Hash`, `From`, `From -> String` and `FromStr` depending on what your type provides. See examples below on how to convert to and from a string. - Convert from Rust's range `a..b`, `a..=b` and so on - Support for `Iterator`, `DoubleEndedIterator`, `ExactSizeIterator` and `IntoIterator` - Support for `Borrow` in parameters to make interface more convenient ## Example ```rust use rust_intervals::{interval, Interval}; let intv1 = Interval::new_closed_open(1, 10); let value = 5; assert!(intv1.contains(&value)); let intv2 = interval!(5, 8, "()"); assert!(intv1.contains_interval(&intv2)); let _ = intv1.convex_hull(&intv2); ``` An interval can be converted to a string using the various standard Rust approaches: ```rust use rust_intervals::{interval, Interval}; let intv1 = Interval::new_closed_open(1, 10); let s = format!("{}", intv1); // using the Display trait let s = intv1.to_string(); // using the ToString trait (via Display) let s = String::from(intv1); // using From>->String trait let s: String = intv1.into(); // using the Into trait let s = "[1, 4]"; let intv = Interval::::from(s); // using From trait let intv: Interval = s.into(); // using Into> trait let intv: Interval = s.parse()?; // using FromStr trait (may fail) ``` ## Testing This library includes extensive testing (`cargo make test-all`), including support for MC/DC coverage (`cargo make cov`, reaching a total of 95.16%, where the remaining uncovered code all seem to be unreachable code). We also work fuzzing tests (`cargo make fuzz`) and random mutations on the code to detect missing tests (`cargo make mutants`). ## Similar packages - `std::ops::Range` are the Rust built-in ranges. They only provide a `contains()` function, do not provide `Copy` and do not provide all the kinds of bounds. - `Extent` [https://docs.rs/extent/latest/extent/] only provide closed-closed intervals. They also do not provide all the operations like `between()`, `convex_hull()` and so forth. In exchange, they do not require extra flags in the struct, which makes them slightly smaller. ## Roadmap The following features are planned. - [ ] Sets of disjoint intervals - [ ] Map from intervals to values (and resolve overlaps to unique values) ## Authors - Emmanuel Briot (Rust version) - Duncan Sands (Ada version it is based on)