inter_val/
nullable.rs

1use crate::{
2    bound_type::{Left, Right},
3    traits::BoundaryOf,
4    Bound, Interval,
5};
6
7/// Wrapper of `Option<T>` to implement `Sum` trait.
8/// ```
9/// use inter_val::{Nullable, Interval, Inclusive, Exclusive};
10/// let a = Inclusive.at(0).to(Exclusive.at(3));  // [0, 3)
11/// let b = Inclusive.at(1).to(Exclusive.at(5));  // [1, 5)
12/// let c = Inclusive.at(8).to(Exclusive.at(10)); // [8, 10)
13/// let span: Nullable<Interval<_, _, _>> = vec![a, b, c].into_iter().sum(); // [0, 10)
14/// assert_eq!(span.as_ref().unwrap().left().limit, 0);
15/// assert_eq!(span.as_ref().unwrap().right().limit, 10);
16///
17/// let hull: Nullable<Interval<i32>> = vec![1, 6, 2, 8, 3].into_iter().sum();
18/// assert_eq!(hull.unwrap(), Interval::between(1, 8));
19/// ```
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
21pub struct Nullable<T>(pub Option<T>);
22
23impl<T> std::ops::Deref for Nullable<T> {
24    type Target = Option<T>;
25    fn deref(&self) -> &Self::Target {
26        &self.0
27    }
28}
29impl<T> std::ops::DerefMut for Nullable<T> {
30    fn deref_mut(&mut self) -> &mut Self::Target {
31        &mut self.0
32    }
33}
34
35impl<T> From<Option<T>> for Nullable<T> {
36    fn from(o: Option<T>) -> Self {
37        Self(o)
38    }
39}
40impl<T> From<T> for Nullable<T> {
41    fn from(t: T) -> Self {
42        Self(Some(t))
43    }
44}
45impl<T> From<Nullable<T>> for Option<T> {
46    fn from(n: Nullable<T>) -> Self {
47        n.0
48    }
49}
50
51impl<T> Nullable<T> {
52    pub const NULL: Self = Self(None);
53
54    pub fn into_option(self) -> Option<T> {
55        self.0
56    }
57    pub fn from_option(o: Option<T>) -> Self {
58        Self(o)
59    }
60    pub fn is_null(&self) -> bool {
61        self.0.is_none()
62    }
63    pub fn unwrap(self) -> T {
64        self.0.unwrap()
65    }
66}
67
68/// ```
69/// use inter_val::{Nullable, Interval, Inclusive, Exclusive};
70/// let a = Inclusive.at(0).to(Exclusive.at(3));  // [0, 3)
71/// let b = Inclusive.at(1).to(Exclusive.at(5));  // [1, 5)
72/// let c = Inclusive.at(8).to(Exclusive.at(10)); // [8, 10)
73/// let span: Nullable<Interval<_, _, _>> = vec![a, b, c].into_iter().sum(); // [0, 10)
74/// assert_eq!(span.as_ref().unwrap().left().limit, 0);
75/// assert_eq!(span.as_ref().unwrap().right().limit, 10);
76/// ```
77impl<T, L, R> std::iter::Sum<Interval<T, L, R>> for Nullable<Interval<T, L, R>>
78where
79    T: PartialOrd + Clone,
80    L: BoundaryOf<Left>,
81    R: BoundaryOf<Right>,
82{
83    fn sum<I: Iterator<Item = Interval<T, L, R>>>(iter: I) -> Self {
84        Interval::span_many(iter).into()
85    }
86}
87
88/// ```
89/// use inter_val::{Interval, Nullable};
90/// let a: Nullable<Interval<i32>> = vec![1, 6, 2, 8, 3].into_iter().sum();
91/// assert_eq!(a.unwrap(), Interval::between(1, 8));
92/// ```
93impl<T, L, R> std::iter::Sum<T> for Nullable<Interval<T, L, R>>
94where
95    T: PartialOrd + Clone + Into<Bound<T, L>> + Into<Bound<T, R>>,
96    L: BoundaryOf<Left>,
97    R: BoundaryOf<Right>,
98{
99    fn sum<I: Iterator<Item = T>>(iter: I) -> Self {
100        Interval::hull_many(iter).into()
101    }
102}
103
104/// ```
105/// use inter_val::{Interval, Nullable};
106/// let a = vec![1, 6, 2, 8, 3].into_iter().collect::<Nullable<Interval<i32>>>();
107/// assert_eq!(a.unwrap(), Interval::between(1, 8));
108/// ```
109impl<T, L, R> std::iter::FromIterator<T> for Nullable<Interval<T, L, R>>
110where
111    T: PartialOrd + Clone + Into<Bound<T, L>> + Into<Bound<T, R>>,
112    L: BoundaryOf<Left>,
113    R: BoundaryOf<Right>,
114{
115    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
116        Interval::hull_many(iter).into()
117    }
118}