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