1use core::{
4 cmp, fmt,
5 ops::{Bound, RangeBounds},
6};
7
8use crate::{seal::Seal, Portable};
9
10#[derive(Clone, Copy, Default, PartialEq, Eq, Hash, Portable)]
12#[cfg_attr(feature = "bytecheck", derive(bytecheck::CheckBytes))]
13#[rkyv(crate)]
14#[repr(C)]
15pub struct ArchivedRangeFull;
16
17impl fmt::Debug for ArchivedRangeFull {
18 #[inline]
19 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
20 write!(fmt, "..")
21 }
22}
23
24#[derive(Clone, Default, PartialEq, Eq, Hash, Portable)]
26#[cfg_attr(feature = "bytecheck", derive(bytecheck::CheckBytes))]
27#[rkyv(crate)]
28#[repr(C)]
29pub struct ArchivedRange<T> {
30 pub start: T,
32 pub end: T,
34}
35
36impl<T: fmt::Debug> fmt::Debug for ArchivedRange<T> {
37 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
38 self.start.fmt(fmt)?;
39 write!(fmt, "..")?;
40 self.end.fmt(fmt)?;
41 Ok(())
42 }
43}
44
45impl<T: PartialOrd<T>> ArchivedRange<T> {
46 pub fn contains<U>(&self, item: &U) -> bool
48 where
49 T: PartialOrd<U>,
50 U: PartialOrd<T> + ?Sized,
51 {
52 <Self as RangeBounds<T>>::contains(self, item)
53 }
54
55 pub fn is_empty(&self) -> bool {
57 match self.start.partial_cmp(&self.end) {
58 None
59 | Some(cmp::Ordering::Greater)
60 | Some(cmp::Ordering::Equal) => true,
61 Some(cmp::Ordering::Less) => false,
62 }
63 }
64}
65
66impl<T> RangeBounds<T> for ArchivedRange<T> {
67 fn start_bound(&self) -> Bound<&T> {
68 Bound::Included(&self.start)
69 }
70
71 fn end_bound(&self) -> Bound<&T> {
72 Bound::Excluded(&self.end)
73 }
74}
75
76#[derive(Clone, Default, PartialEq, Eq, Hash, Portable)]
78#[cfg_attr(feature = "bytecheck", derive(bytecheck::CheckBytes))]
79#[rkyv(crate)]
80#[repr(C)]
81pub struct ArchivedRangeInclusive<T> {
82 pub start: T,
84 pub end: T,
86}
87
88impl<T: fmt::Debug> fmt::Debug for ArchivedRangeInclusive<T> {
89 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
90 self.start.fmt(fmt)?;
91 write!(fmt, "..=")?;
92 self.end.fmt(fmt)?;
93 Ok(())
94 }
95}
96
97impl<T: PartialOrd<T>> ArchivedRangeInclusive<T> {
98 pub fn contains<U>(&self, item: &U) -> bool
100 where
101 T: PartialOrd<U>,
102 U: PartialOrd<T> + ?Sized,
103 {
104 <Self as RangeBounds<T>>::contains(self, item)
105 }
106
107 pub fn is_empty(&self) -> bool {
109 match self.start.partial_cmp(&self.end) {
110 None | Some(cmp::Ordering::Greater) => true,
111 Some(cmp::Ordering::Less) | Some(cmp::Ordering::Equal) => false,
112 }
113 }
114}
115
116impl<T> RangeBounds<T> for ArchivedRangeInclusive<T> {
117 fn start_bound(&self) -> Bound<&T> {
118 Bound::Included(&self.start)
119 }
120
121 fn end_bound(&self) -> Bound<&T> {
122 Bound::Included(&self.end)
123 }
124}
125
126#[derive(Clone, Default, PartialEq, Eq, Hash, Portable)]
128#[cfg_attr(feature = "bytecheck", derive(bytecheck::CheckBytes))]
129#[rkyv(crate)]
130#[repr(C)]
131pub struct ArchivedRangeFrom<T> {
132 pub start: T,
134}
135
136impl<T: fmt::Debug> fmt::Debug for ArchivedRangeFrom<T> {
137 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
138 self.start.fmt(fmt)?;
139 write!(fmt, "..")?;
140 Ok(())
141 }
142}
143
144impl<T: PartialOrd<T>> ArchivedRangeFrom<T> {
145 pub fn contains<U>(&self, item: &U) -> bool
147 where
148 T: PartialOrd<U>,
149 U: ?Sized + PartialOrd<T>,
150 {
151 <Self as RangeBounds<T>>::contains(self, item)
152 }
153}
154
155impl<T> RangeBounds<T> for ArchivedRangeFrom<T> {
156 fn start_bound(&self) -> Bound<&T> {
157 Bound::Included(&self.start)
158 }
159
160 fn end_bound(&self) -> Bound<&T> {
161 Bound::Unbounded
162 }
163}
164
165#[derive(Clone, Default, PartialEq, Eq, Hash, Portable)]
167#[cfg_attr(feature = "bytecheck", derive(bytecheck::CheckBytes))]
168#[rkyv(crate)]
169#[repr(C)]
170pub struct ArchivedRangeTo<T> {
171 pub end: T,
173}
174
175impl<T: fmt::Debug> fmt::Debug for ArchivedRangeTo<T> {
176 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
177 write!(fmt, "..")?;
178 self.end.fmt(fmt)?;
179 Ok(())
180 }
181}
182
183impl<T: PartialOrd<T>> ArchivedRangeTo<T> {
184 pub fn contains<U>(&self, item: &U) -> bool
186 where
187 T: PartialOrd<U>,
188 U: ?Sized + PartialOrd<T>,
189 {
190 <Self as RangeBounds<T>>::contains(self, item)
191 }
192}
193
194impl<T> RangeBounds<T> for ArchivedRangeTo<T> {
195 fn start_bound(&self) -> Bound<&T> {
196 Bound::Unbounded
197 }
198
199 fn end_bound(&self) -> Bound<&T> {
200 Bound::Excluded(&self.end)
201 }
202}
203
204#[derive(Clone, Default, PartialEq, Eq, Hash, Portable)]
206#[cfg_attr(feature = "bytecheck", derive(bytecheck::CheckBytes))]
207#[rkyv(crate)]
208#[repr(C)]
209pub struct ArchivedRangeToInclusive<T> {
210 pub end: T,
212}
213
214impl<T: fmt::Debug> fmt::Debug for ArchivedRangeToInclusive<T> {
215 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
216 write!(fmt, "..=")?;
217 self.end.fmt(fmt)?;
218 Ok(())
219 }
220}
221
222impl<T: PartialOrd<T>> ArchivedRangeToInclusive<T> {
223 pub fn contains<U>(&self, item: &U) -> bool
225 where
226 T: PartialOrd<U>,
227 U: ?Sized + PartialOrd<T>,
228 {
229 <Self as RangeBounds<T>>::contains(self, item)
230 }
231}
232
233impl<T> RangeBounds<T> for ArchivedRangeToInclusive<T> {
234 fn start_bound(&self) -> Bound<&T> {
235 Bound::Unbounded
236 }
237
238 fn end_bound(&self) -> Bound<&T> {
239 Bound::Included(&self.end)
240 }
241}
242
243#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Portable)]
245#[cfg_attr(feature = "bytecheck", derive(bytecheck::CheckBytes))]
246#[repr(u8)]
247#[rkyv(crate)]
248pub enum ArchivedBound<T> {
249 Included(T),
251 Excluded(T),
253 Unbounded,
256}
257
258impl<T> ArchivedBound<T> {
259 pub fn as_ref(&self) -> Bound<&T> {
261 match self {
262 ArchivedBound::Included(x) => Bound::Included(x),
263 ArchivedBound::Excluded(x) => Bound::Excluded(x),
264 ArchivedBound::Unbounded => Bound::Unbounded,
265 }
266 }
267
268 pub fn as_mut(&mut self) -> Bound<&mut T> {
270 match self {
271 ArchivedBound::Included(x) => Bound::Included(x),
272 ArchivedBound::Excluded(x) => Bound::Excluded(x),
273 ArchivedBound::Unbounded => Bound::Unbounded,
274 }
275 }
276
277 pub fn as_seal(this: Seal<'_, Self>) -> Bound<Seal<'_, T>> {
279 let this = unsafe { Seal::unseal_unchecked(this) };
280 match this {
281 ArchivedBound::Included(x) => Bound::Included(Seal::new(x)),
282 ArchivedBound::Excluded(x) => Bound::Excluded(Seal::new(x)),
283 ArchivedBound::Unbounded => Bound::Unbounded,
284 }
285 }
286}