## **`intervalx`**
[](https://crates.io/crates/intervalx)
[](https://docs.rs/intervalx)
**Generic Interval and IntervalSet algebra crate**
* *This crate is pure **generic** interval algebra, and can be implemented for any type*
* main-types :
`intervalx::interval::Interval<T:Ord+IntervalBound>`
`intervalx::set::IntervalSet<T:Ord+IntervalBound>`
## `Key Features`
* Mathematically correct interval types: open, closed, left_open, right_open, point, empty, and unbounded.
* Generic over numeric types: Works out-of-the-box with standard primitives (i32, i64, u32, u64, f32, f64).
* Extensible via `IntervalBound` trait: Allows users to define intervals for custom numeric types, units, or domain-specific numbers.
* Safe empty interval handling: Automatically handles degenerate intervals like `(5,5)`.
* Unbounded intervals: Represent full numeric ranges using practical finite bounds (MIN/MAX) of the user-implemented type for real-world safety, in other words `[-Inf,+inf] interval` for `i32` is actually `[i32::MIN,i32::MAX]` as implemented for default.
* Contains checks: Easily test if a value is inside an interval *with `.contains(&x)`.
* Algebraic operations: Supports intersect, union, overlaps, and adjacency checks (planned for advanced versions).
* Beginner-friendly defaults: Use immediately with standard numeric types; no trait implementation required.
* Advanced usage: Fully generic and type-safe for experts needing custom types or unit-safe intervals.
* Readable algebraic notation: Intervals are displayed in standard mathematical forms `(a,b)`, `[a,b]`, `(a,b]`, `[a,b)`.
## `Rules`
* `intervalx::interval::IntervalBound` Trait and `std::cmp::Ord` Trait must be implemented for any type that
want to use `Interval<T>`
* default implementation of `IntervalBound` is supplied for `i8`,`i16`,`i32`,`i64`,`i128`,`u8`,`u16`,`u32`,`u64`,`u128`.
* `intervalx::bound::Bound(Open(x))` excludes x
* `intervalx::bound::Bound(Closed(x))` includes x
## for better understanding review documentation
## Examples
* Basic usage:
```rust
use intervalx::interval::*;
let open_interval=Interval::open(5, 7); println!("{}",open_interval);
assert!(open_interval.contains(&6));
let closed_interval=Interval::closed(5, 6); println!("{}",closed_interval);
assert!(closed_interval.contains(&5));
assert!(closed_interval.contains(&6));
let left_open=Interval::left_open(5, 6); println!("{}",left_open);
assert!(left_open.contains(&6));
assert!(!left_open.contains(&5));
let right_open=Interval::right_open(5, 6); println!("{}",right_open);
assert!(right_open.contains(&5));
assert!(!right_open.contains(&6));
let unbounded=Interval::unbounded(); println!("{}",unbounded);
for i in -50..=50 {
assert!(unbounded.contains(&i))
}
let empty_interval:Interval<i32>=Interval::empty();
println!("{}",empty_interval);
let empty_interval1=Interval::open(5, 5); println!("{}",empty_interval1);
let empty_interval2=Interval::left_open(5, 5); println!("{}",empty_interval2);
for i in -50..=50{
assert!(!empty_interval.contains(&i));
assert!(!empty_interval1.contains(&i));
assert!(!empty_interval2.contains(&i));
}
```
* basic methods
```rust
use intervalx::interval::*;
let a_b=Interval::closed(-1, 1);
let c_d=Interval::closed(1, 3);
let a_b_intersects_c_d=a_b.intersection(&c_d);
println!("{}",a_b_intersects_c_d);
assert!(a_b_intersects_c_d.contains(&1));
let inf_=Interval::left_open(1,i64::MAX);
println!("{}",inf_);
let open1=Interval::open(-1, 5);
let b=Interval::open(-1, 4);
let isn=open1.intersection(&b);
println!("isn: {}",isn);
assert!(!isn.contains(&5));
println!("#########################");
let a = Interval::closed(9, 10); let b = Interval::closed(1, 8);
let i = a.intersection(&b);
println!("intersection: {}",i);
let a = Interval::closed(1, 2);
let b = Interval::closed(2, 3);
let i=a.intersection(&b);
println!("{}",i);
let a=Interval::open(1, 5);
let b=Interval::closed(1, 5);
let i=a.intersection(&b);
println!("I: {}",i);
let age_interval=Interval::closed(HumanAge::min_limit(), HumanAge::max_limit());
println!("age-interval : {}",age_interval);
let ossama_age=HumanAge{ age:31 };
assert!(age_interval.contains(&ossama_age));
let a:Interval<i32>=Interval::unbounded();
let b=Interval::unbounded();
let i=a.intersection(&b);
println!("bounded ∩ open : {i}");
let a=Interval::right_open(1, 3);
let b=Interval::closed(3, 5);
println!("{}",a.intersection(&b));
let a=Interval::right_open(1, 3);
let b=Interval::closed(3, 5);
println!("{}",a.is_adjacent(&b));
```
# Advanced Usage (Custom Types)
```rust
use std::fmt::{Debug, Display};
use intervalx::interval::*;
use intervalx::set::*;
#[derive(PartialEq, Clone, Eq, PartialOrd, Ord, Debug)]
struct NetworkPort(u16);
impl IntervalBound for NetworkPort {
fn min_limit() -> Self {
NetworkPort(0)
}
fn max_limit() -> Self {
NetworkPort(65535)
}
}
impl Display for NetworkPort {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f,"port({})",&self.0)
}
}
fn main(){
let port_interval:Interval<NetworkPort>=Interval::unbounded();
println!("{}",port_interval);
let port_8080=NetworkPort(8080);
assert!(port_interval.contains(&port_8080));
}
```