rust_intervals 1.0.1

Intervals arithmetic with any combination of open, closed or infinite bounds, along with operations like intersection, convex hull, union, difference,...
# 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<String>`, `From<Interval> -> 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<Interval<T>>->String trait
   let s: String = intv1.into();  // using the Into<String> trait

   let s = "[1, 4]";
   let intv = Interval::<u32>::from(s);  // using From<String> trait
   let intv: Interval<u32> = s.into();   // using Into<Interval<T>> trait
   let intv: Interval<u32> = 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)