1use crate::{
2 bound_type::{Left, Right},
3 traits::BoundaryOf,
4 Bound, Interval,
5};
6
7#[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
68impl<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
88impl<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
104impl<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}