closed_interval_set/
range_case.rs1use alloc::vec::Vec;
5use smallvec::SmallVec;
6
7use crate::Backing;
8use crate::Endpoint;
9use crate::RangeVec;
10
11pub struct RangeCase<T: Endpoint> {
17 inner: Backing<T>,
18 normalized: bool,
19}
20
21impl<T: Endpoint> RangeCase<T> {
22 #[inline(always)]
26 pub fn from_vec(inner: Vec<(T, T)>) -> Self {
27 Self {
28 inner: inner.into(),
29 normalized: false,
30 }
31 }
32
33 #[inline(always)]
37 pub fn from_smallvec<const N: usize>(inner: SmallVec<[(T, T); N]>) -> Self {
38 #[cfg_attr(
40 not(feature = "inline_storage"),
41 allow(clippy::absurd_extreme_comparisons)
42 )]
43 let inner: Backing<T> = if inner.len() <= crate::INLINE_SIZE {
44 inner.into_iter().collect()
45 } else {
46 inner.into_vec().into()
47 };
48
49 Self {
50 inner,
51 normalized: false,
52 }
53 }
54
55 #[inline(always)]
59 pub fn from_range_vec(set: RangeVec<T>) -> Self {
60 Self {
61 inner: set.into_inner(),
62 normalized: true,
63 }
64 }
65
66 #[inline(always)]
70 pub fn into_inner(self) -> Backing<T> {
71 self.inner
72 }
73
74 #[inline(always)]
79 pub fn unerase(self) -> Result<RangeVec<T>, Backing<T>> {
80 if self.normalized {
81 Ok(unsafe { RangeVec::new_unchecked(self.inner) })
82 } else {
83 Err(self.inner)
84 }
85 }
86}
87
88impl<T: Endpoint> From<RangeVec<T>> for RangeCase<T> {
89 #[inline(always)]
90 fn from(item: RangeVec<T>) -> RangeCase<T> {
91 RangeCase::from_range_vec(item)
92 }
93}
94
95impl<T: Endpoint> From<Vec<(T, T)>> for RangeCase<T> {
96 #[inline(always)]
97 fn from(item: Vec<(T, T)>) -> RangeCase<T> {
98 RangeCase::from_vec(item)
99 }
100}
101
102impl<T: Endpoint, const N: usize> From<SmallVec<[(T, T); N]>> for RangeCase<T> {
103 #[inline(always)]
104 fn from(item: SmallVec<[(T, T); N]>) -> RangeCase<T> {
105 RangeCase::from_smallvec(item)
106 }
107}
108
109#[cfg_attr(coverage_nightly, coverage(off))]
110#[test]
111fn test_smoke() {
112 use alloc::vec;
113 use smallvec::smallvec;
114
115 let x: RangeCase<_> = vec![(1u8, 2u8)].into();
116 assert_eq!(x.into_inner().into_vec(), vec![(1u8, 2u8)]);
117
118 let smallvec: Backing<u8> = smallvec![(1u8, 2u8)];
119 let x: RangeCase<_> = smallvec.into();
120 assert_eq!(x.unerase().unwrap_err().into_vec(), vec![(1u8, 2u8)]);
121
122 let smallervec: SmallVec<[(u8, u8); 0]> = smallvec![(1u8, 2u8)];
123 let x: RangeCase<_> = smallervec.into();
124 assert_eq!(x.unerase().unwrap_err().into_vec(), vec![(1u8, 2u8)]);
125
126 let largervec: SmallVec<[(u8, u8); crate::INLINE_SIZE + 1]> = smallvec![(1u8, 2u8)];
127 let x: RangeCase<_> = largervec.into();
128 assert_eq!(x.unerase().unwrap_err().into_vec(), vec![(1u8, 2u8)]);
129
130 let vec = unsafe { RangeVec::new_unchecked(smallvec![(1u8, 2u8)]) };
131 let x: RangeCase<_> = vec.clone().into();
132 assert_eq!(x.unerase().unwrap(), vec);
133}