[go: up one dir, main page]

rkyv/
ops.rs

1//! Archived versions of `ops` types.
2
3use core::{
4    cmp, fmt,
5    ops::{Bound, RangeBounds},
6};
7
8use crate::{seal::Seal, Portable};
9
10/// An archived [`RangeFull`](::core::ops::RangeFull).
11#[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/// An archived [`Range`](::core::ops::Range).
25#[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    /// The lower bound of the range (inclusive).
31    pub start: T,
32    /// The upper bound of the range (inclusive).
33    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    /// Returns `true` if `item` is contained in the range.
47    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    /// Returns `true` if the range contains no items.
56    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/// An archived [`RangeInclusive`](::core::ops::RangeInclusive).
77#[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    /// The lower bound of the range (inclusive).
83    pub start: T,
84    /// The upper bound of the range (inclusive).
85    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    /// Returns `true` if `item` is contained in the range.
99    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    /// Returns `true` if the range contains no items.
108    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/// An archived [`RangeFrom`](::core::ops::RangeFrom).
127#[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    /// The lower bound of the range (inclusive).
133    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    /// Returns `true` if `item` is contained in the range.
146    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/// An archived [`RangeTo`](::core::ops::RangeTo).
166#[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    /// The upper bound of the range (exclusive).
172    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    /// Returns `true` if `item` is contained in the range.
185    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/// An archived [`RangeToInclusive`](::core::ops::RangeToInclusive).
205#[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    /// The upper bound of the range (inclusive).
211    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    /// Returns `true` if `item` is contained in the range.
224    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/// An archived [`Bound`].
244#[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    /// An inclusive bound.
250    Included(T),
251    /// An exclusive bound.
252    Excluded(T),
253    /// An infinite endpoint. Indicates that there is no bound in this
254    /// direction.
255    Unbounded,
256}
257
258impl<T> ArchivedBound<T> {
259    /// Converts from `&ArchivedBound<T>` to `Bound<&T>`.
260    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    /// Converts from `&mut ArchivedBound<T>` to `Bound<&mut T>`.
269    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    /// Converts from `Seal<&ArchivedBound<T>>` to `Bound<Seal<&T>>`.
278    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}