allen_intervals/
non_empty.rs1use core::cmp::Ordering;
2
3use crate::{Interval, IntervalError, IntervalFrom, IntervalFull, IntervalTo};
4
5#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
12#[repr(transparent)]
13pub struct NonEmpty<T>(pub(crate) T);
14
15impl<T> NonEmpty<T> {
16 #[inline]
23 pub unsafe fn new_unchecked(value: T) -> Self {
24 Self(value)
25 }
26}
27
28impl<T> TryFrom<Interval<T>> for NonEmpty<Interval<T>>
29where
30 T: PartialOrd,
31{
32 type Error = IntervalError;
33
34 fn try_from(value: Interval<T>) -> Result<Self, Self::Error> {
35 match value.start.partial_cmp(&value.end) {
36 Some(Ordering::Less) => Ok(Self(value)),
37 Some(Ordering::Equal) => Err(IntervalError::EmptyInterval),
38 Some(Ordering::Greater) => Err(IntervalError::EmptyInterval),
39 None => Err(IntervalError::AmbiguousOrder),
40 }
41 }
42}
43
44impl<T> From<IntervalTo<T>> for NonEmpty<IntervalTo<T>> {
45 #[inline]
46 fn from(value: IntervalTo<T>) -> Self {
47 Self(value)
48 }
49}
50
51impl<T> From<IntervalFrom<T>> for NonEmpty<IntervalFrom<T>> {
52 #[inline]
53 fn from(value: IntervalFrom<T>) -> Self {
54 Self(value)
55 }
56}
57
58impl From<IntervalFull> for NonEmpty<IntervalFull> {
59 #[inline]
60 fn from(value: IntervalFull) -> Self {
61 Self(value)
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn non_empty() {
71 let min = isize::min_value();
72 let mid = 0;
73 let max = isize::max_value();
74
75 assert_eq!(
76 NonEmpty::try_from(Interval {
77 start: min,
78 end: min
79 }),
80 Err(IntervalError::EmptyInterval)
81 );
82 assert_eq!(
83 NonEmpty::try_from(Interval {
84 start: mid,
85 end: mid
86 }),
87 Err(IntervalError::EmptyInterval)
88 );
89 assert_eq!(
90 NonEmpty::try_from(Interval {
91 start: max,
92 end: max
93 }),
94 Err(IntervalError::EmptyInterval)
95 );
96
97 assert_eq!(
98 NonEmpty::try_from(Interval {
99 start: max,
100 end: mid
101 }),
102 Err(IntervalError::EmptyInterval)
103 );
104 assert_eq!(
105 NonEmpty::try_from(Interval {
106 start: mid,
107 end: min
108 }),
109 Err(IntervalError::EmptyInterval)
110 );
111
112 assert_eq!(
113 NonEmpty::try_from(Interval {
114 start: min,
115 end: mid
116 }),
117 Ok(NonEmpty(Interval {
118 start: min,
119 end: mid
120 }))
121 );
122 assert_eq!(
123 NonEmpty::try_from(Interval {
124 start: mid,
125 end: max
126 }),
127 Ok(NonEmpty(Interval {
128 start: mid,
129 end: max
130 }))
131 );
132 }
133}