1use core::{
2 hint::unreachable_unchecked,
3 ops::{
4 Bound, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo,
5 RangeToInclusive,
6 },
7};
8
9use munge::munge;
10use rancor::Fallible;
11
12use crate::{
13 ops::{
14 ArchivedBound, ArchivedRange, ArchivedRangeFrom, ArchivedRangeFull,
15 ArchivedRangeInclusive, ArchivedRangeTo, ArchivedRangeToInclusive,
16 },
17 traits::{CopyOptimization, NoUndef},
18 Archive, Deserialize, Place, Serialize,
19};
20
21impl Archive for RangeFull {
24 const COPY_OPTIMIZATION: CopyOptimization<Self> =
25 unsafe { CopyOptimization::enable() };
26
27 type Archived = ArchivedRangeFull;
28 type Resolver = ();
29
30 #[inline]
31 fn resolve(&self, _: Self::Resolver, _: Place<Self::Archived>) {}
32}
33
34impl<S: Fallible + ?Sized> Serialize<S> for RangeFull {
35 fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
36 Ok(())
37 }
38}
39
40impl<D: Fallible + ?Sized> Deserialize<RangeFull, D> for ArchivedRangeFull {
41 fn deserialize(&self, _: &mut D) -> Result<RangeFull, D::Error> {
42 Ok(RangeFull)
43 }
44}
45
46impl PartialEq<RangeFull> for ArchivedRangeFull {
47 fn eq(&self, _: &RangeFull) -> bool {
48 true
49 }
50}
51
52impl<T: Archive> Archive for Range<T> {
55 type Archived = ArchivedRange<T::Archived>;
56 type Resolver = Range<T::Resolver>;
57
58 fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
59 munge!(let ArchivedRange { start, end } = out);
60 self.start.resolve(resolver.start, start);
61 self.end.resolve(resolver.end, end);
62 }
63}
64
65impl<T: Serialize<S>, S: Fallible + ?Sized> Serialize<S> for Range<T> {
66 fn serialize(
67 &self,
68 serializer: &mut S,
69 ) -> Result<Self::Resolver, S::Error> {
70 Ok(Range {
71 start: self.start.serialize(serializer)?,
72 end: self.end.serialize(serializer)?,
73 })
74 }
75}
76
77impl<T, D> Deserialize<Range<T>, D> for ArchivedRange<T::Archived>
78where
79 T: Archive,
80 T::Archived: Deserialize<T, D>,
81 D: Fallible + ?Sized,
82{
83 fn deserialize(&self, deserializer: &mut D) -> Result<Range<T>, D::Error> {
84 Ok(Range {
85 start: self.start.deserialize(deserializer)?,
86 end: self.end.deserialize(deserializer)?,
87 })
88 }
89}
90
91impl<T, U: PartialEq<T>> PartialEq<Range<T>> for ArchivedRange<U> {
92 fn eq(&self, other: &Range<T>) -> bool {
93 self.start.eq(&other.start) && self.end.eq(&other.end)
94 }
95}
96
97impl<T: Archive> Archive for RangeInclusive<T> {
100 type Archived = ArchivedRangeInclusive<T::Archived>;
101 type Resolver = Range<T::Resolver>;
102
103 fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
104 munge!(let ArchivedRangeInclusive { start, end } = out);
105 self.start().resolve(resolver.start, start);
106 self.end().resolve(resolver.end, end);
107 }
108}
109
110impl<T: Serialize<S>, S: Fallible + ?Sized> Serialize<S> for RangeInclusive<T> {
111 fn serialize(
112 &self,
113 serializer: &mut S,
114 ) -> Result<Self::Resolver, S::Error> {
115 Ok(Range {
116 start: self.start().serialize(serializer)?,
117 end: self.end().serialize(serializer)?,
118 })
119 }
120}
121
122impl<T, D> Deserialize<RangeInclusive<T>, D>
123 for ArchivedRangeInclusive<T::Archived>
124where
125 T: Archive,
126 T::Archived: Deserialize<T, D>,
127 D: Fallible + ?Sized,
128{
129 fn deserialize(
130 &self,
131 deserializer: &mut D,
132 ) -> Result<RangeInclusive<T>, D::Error> {
133 Ok(RangeInclusive::new(
134 self.start.deserialize(deserializer)?,
135 self.end.deserialize(deserializer)?,
136 ))
137 }
138}
139
140impl<T, U> PartialEq<RangeInclusive<T>> for ArchivedRangeInclusive<U>
141where
142 U: PartialEq<T>,
143{
144 fn eq(&self, other: &RangeInclusive<T>) -> bool {
145 self.start.eq(other.start()) && self.end.eq(other.end())
146 }
147}
148
149impl<T: Archive> Archive for RangeFrom<T> {
152 type Archived = ArchivedRangeFrom<T::Archived>;
153 type Resolver = RangeFrom<T::Resolver>;
154
155 fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
156 munge!(let ArchivedRangeFrom { start } = out);
157 self.start.resolve(resolver.start, start);
158 }
159}
160
161impl<T: Serialize<S>, S: Fallible + ?Sized> Serialize<S> for RangeFrom<T> {
162 fn serialize(
163 &self,
164 serializer: &mut S,
165 ) -> Result<Self::Resolver, S::Error> {
166 Ok(RangeFrom {
167 start: self.start.serialize(serializer)?,
168 })
169 }
170}
171
172impl<T, D> Deserialize<RangeFrom<T>, D> for ArchivedRangeFrom<T::Archived>
173where
174 T: Archive,
175 D: Fallible + ?Sized,
176 T::Archived: Deserialize<T, D>,
177{
178 fn deserialize(
179 &self,
180 deserializer: &mut D,
181 ) -> Result<RangeFrom<T>, D::Error> {
182 Ok(RangeFrom {
183 start: self.start.deserialize(deserializer)?,
184 })
185 }
186}
187
188impl<T, U: PartialEq<T>> PartialEq<RangeFrom<T>> for ArchivedRangeFrom<U> {
189 fn eq(&self, other: &RangeFrom<T>) -> bool {
190 self.start.eq(&other.start)
191 }
192}
193
194impl<T: Archive> Archive for RangeTo<T> {
197 type Archived = ArchivedRangeTo<T::Archived>;
198 type Resolver = RangeTo<T::Resolver>;
199
200 fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
201 munge!(let ArchivedRangeTo { end } = out);
202 self.end.resolve(resolver.end, end);
203 }
204}
205
206impl<T: Serialize<S>, S: Fallible + ?Sized> Serialize<S> for RangeTo<T> {
207 fn serialize(
208 &self,
209 serializer: &mut S,
210 ) -> Result<Self::Resolver, S::Error> {
211 Ok(RangeTo {
212 end: self.end.serialize(serializer)?,
213 })
214 }
215}
216
217impl<T, D> Deserialize<RangeTo<T>, D> for ArchivedRangeTo<T::Archived>
218where
219 T: Archive,
220 D: Fallible + ?Sized,
221 T::Archived: Deserialize<T, D>,
222{
223 fn deserialize(
224 &self,
225 deserializer: &mut D,
226 ) -> Result<RangeTo<T>, D::Error> {
227 Ok(RangeTo {
228 end: self.end.deserialize(deserializer)?,
229 })
230 }
231}
232
233impl<T, U: PartialEq<T>> PartialEq<RangeTo<T>> for ArchivedRangeTo<U> {
234 fn eq(&self, other: &RangeTo<T>) -> bool {
235 self.end.eq(&other.end)
236 }
237}
238
239impl<T: Archive> Archive for RangeToInclusive<T> {
242 type Archived = ArchivedRangeToInclusive<T::Archived>;
243 type Resolver = RangeToInclusive<T::Resolver>;
244
245 fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
246 munge!(let ArchivedRangeToInclusive { end } = out);
247 self.end.resolve(resolver.end, end);
248 }
249}
250
251impl<T, S> Serialize<S> for RangeToInclusive<T>
252where
253 T: Serialize<S>,
254 S: Fallible + ?Sized,
255{
256 fn serialize(
257 &self,
258 serializer: &mut S,
259 ) -> Result<Self::Resolver, S::Error> {
260 Ok(RangeToInclusive {
261 end: self.end.serialize(serializer)?,
262 })
263 }
264}
265
266impl<T, D> Deserialize<RangeToInclusive<T>, D>
267 for ArchivedRangeToInclusive<T::Archived>
268where
269 T: Archive,
270 T::Archived: Deserialize<T, D>,
271 D: Fallible + ?Sized,
272{
273 fn deserialize(
274 &self,
275 deserializer: &mut D,
276 ) -> Result<RangeToInclusive<T>, D::Error> {
277 Ok(RangeToInclusive {
278 end: self.end.deserialize(deserializer)?,
279 })
280 }
281}
282
283impl<T, U> PartialEq<RangeToInclusive<T>> for ArchivedRangeToInclusive<U>
284where
285 U: PartialEq<T>,
286{
287 fn eq(&self, other: &RangeToInclusive<T>) -> bool {
288 self.end.eq(&other.end)
289 }
290}
291
292#[allow(dead_code)]
295#[repr(u8)]
296enum ArchivedBoundTag {
297 Included,
298 Excluded,
299 Unbounded,
300}
301
302unsafe impl NoUndef for ArchivedBoundTag {}
305
306#[repr(C)]
307struct ArchivedBoundVariantIncluded<T>(ArchivedBoundTag, T);
308
309#[repr(C)]
310struct ArchivedBoundVariantExcluded<T>(ArchivedBoundTag, T);
311
312#[repr(C)]
313struct ArchivedBoundVariantUnbounded(ArchivedBoundTag);
314
315impl<T: Archive> Archive for Bound<T> {
316 type Archived = ArchivedBound<T::Archived>;
317 type Resolver = Bound<T::Resolver>;
318
319 fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
320 match resolver {
321 Bound::Included(resolver) => {
322 let out = unsafe {
323 out.cast_unchecked::<
324 ArchivedBoundVariantIncluded<T::Archived>
325 >()
326 };
327 munge!(let ArchivedBoundVariantIncluded(tag, out_value) = out);
328 tag.write(ArchivedBoundTag::Included);
329
330 let value = if let Bound::Included(value) = self.as_ref() {
331 value
332 } else {
333 unsafe {
334 unreachable_unchecked();
335 }
336 };
337
338 value.resolve(resolver, out_value);
339 }
340 Bound::Excluded(resolver) => {
341 let out = unsafe {
342 out.cast_unchecked::<
343 ArchivedBoundVariantExcluded<T::Archived>
344 >()
345 };
346 munge!(let ArchivedBoundVariantExcluded(tag, out_value) = out);
347 tag.write(ArchivedBoundTag::Excluded);
348
349 let value = if let Bound::Excluded(value) = self.as_ref() {
350 value
351 } else {
352 unsafe {
353 unreachable_unchecked();
354 }
355 };
356
357 value.resolve(resolver, out_value);
358 }
359 Bound::Unbounded => {
360 let out = unsafe {
361 out.cast_unchecked::<ArchivedBoundVariantUnbounded>()
362 };
363 munge!(let ArchivedBoundVariantUnbounded(tag) = out);
364 tag.write(ArchivedBoundTag::Unbounded);
365 }
366 }
367 }
368}
369
370impl<T: Serialize<S>, S: Fallible + ?Sized> Serialize<S> for Bound<T> {
371 fn serialize(
372 &self,
373 serializer: &mut S,
374 ) -> Result<Self::Resolver, S::Error> {
375 match self.as_ref() {
376 Bound::Included(x) => x.serialize(serializer).map(Bound::Included),
377 Bound::Excluded(x) => x.serialize(serializer).map(Bound::Excluded),
378 Bound::Unbounded => Ok(Bound::Unbounded),
379 }
380 }
381}
382
383impl<T, D> Deserialize<Bound<T>, D> for ArchivedBound<T::Archived>
384where
385 T: Archive,
386 T::Archived: Deserialize<T, D>,
387 D: Fallible + ?Sized,
388{
389 fn deserialize(
390 &self,
391 deserializer: &mut D,
392 ) -> Result<Bound<T>, <D as Fallible>::Error> {
393 Ok(match self {
394 ArchivedBound::Included(value) => {
395 Bound::Included(value.deserialize(deserializer)?)
396 }
397 ArchivedBound::Excluded(value) => {
398 Bound::Excluded(value.deserialize(deserializer)?)
399 }
400 ArchivedBound::Unbounded => Bound::Unbounded,
401 })
402 }
403}
404
405impl<T, U> PartialEq<Bound<T>> for ArchivedBound<U>
406where
407 U: PartialEq<T>,
408{
409 fn eq(&self, other: &Bound<T>) -> bool {
410 match (self, other) {
411 (ArchivedBound::Included(this), Bound::Included(other))
412 | (ArchivedBound::Excluded(this), Bound::Excluded(other)) => {
413 this.eq(other)
414 }
415 (ArchivedBound::Unbounded, Bound::Unbounded) => true,
416 _ => false,
417 }
418 }
419}
420
421#[cfg(test)]
422mod tests {
423 use core::ops::Bound;
424
425 use crate::api::test::roundtrip;
426
427 #[test]
428 fn roundtrip_ranges() {
429 roundtrip(&..);
430 roundtrip(&(0u8..100u8));
431 roundtrip(&(0u8..=100u8));
432 roundtrip(&(0u8..));
433 roundtrip(&(..100u8));
434 roundtrip(&(..=100u8));
435 }
436
437 #[test]
438 fn roundtrip_bound() {
439 roundtrip(&Bound::Included(100u8));
440 roundtrip(&Bound::Excluded(100u8));
441 roundtrip(&Bound::<u8>::Unbounded);
442 }
443}