more_ranges/
range_from_exclusive.rs

1#[cfg(feature = "serde")]
2use crate::string;
3#[cfg(feature = "alloc")]
4use alloc::{string::String, vec::Vec};
5use core::{
6    ffi::CStr,
7    iter::FusedIterator,
8    ops::{
9        Bound::{self, Excluded, Unbounded},
10        Index, IndexMut, RangeBounds, RangeFrom,
11    },
12};
13#[cfg(feature = "serde")]
14use core::{fmt, fmt::Formatter, marker::PhantomData};
15#[cfg(feature = "serde")]
16use serde_core::{
17    de,
18    de::{Deserialize, Deserializer, Error as _, MapAccess, SeqAccess, Visitor},
19    ser::{Serialize, SerializeStruct, Serializer},
20};
21
22/// A range only bounded exclusively below.
23///
24/// The `RangeFromExclusive` contains all values with `x > start`.
25///
26/// *Note*: Overflow in the [`Iterator`] implementation (when the contained data type reaches its
27/// numerical limit) is allowed to panic, wrap, or saturate. This behavior is defined by the
28/// implementation of the [`Step`] trait. For primitive integers, this follows the normal rules, and
29/// respects the overflow checks profile (panic in debug, wrap in release).
30///
31/// # Example
32/// `RangeFromExclusive`s can be created directly, as follows:
33///
34/// ```
35/// use more_ranges::RangeFromExclusive;
36///
37/// let range = RangeFromExclusive {
38///     start: 1,
39/// };
40/// ```
41///
42/// [`Iterator`]: core::iter::Iterator
43/// [`Step`]: core::iter::Step
44#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
45pub struct RangeFromExclusive<T> {
46    /// The lower bound of the range (exclusive).
47    pub start: T,
48}
49
50impl<T> RangeFromExclusive<T> {
51    /// Since implementations for many standard library traits for built-in range types rely on
52    /// nightly features, we implement those traits here by converting into standard library range
53    /// types. This allows these traits to be implemented without enabling nightly features.
54    #[inline]
55    fn into_range_from(self) -> RangeFrom<T>
56    where
57        RangeFrom<T>: Iterator,
58    {
59        let mut range_from = RangeFrom { start: self.start };
60        // Advance by one so we don't include the first value.
61        range_from.next();
62        range_from
63    }
64}
65
66impl<T> RangeBounds<T> for RangeFromExclusive<T> {
67    #[inline]
68    fn start_bound(&self) -> Bound<&T> {
69        Excluded(&self.start)
70    }
71
72    #[inline]
73    fn end_bound(&self) -> Bound<&T> {
74        Unbounded
75    }
76}
77
78impl<'a, T> RangeBounds<T> for RangeFromExclusive<&'a T> {
79    #[inline]
80    fn start_bound(&self) -> Bound<&T> {
81        Excluded(self.start)
82    }
83
84    #[inline]
85    fn end_bound(&self) -> Bound<&T> {
86        Unbounded
87    }
88}
89
90impl<T> Index<RangeFromExclusive<usize>> for [T] {
91    type Output = <[T] as Index<RangeFrom<usize>>>::Output;
92
93    #[inline]
94    fn index(&self, index: RangeFromExclusive<usize>) -> &Self::Output {
95        self.index(index.into_range_from())
96    }
97}
98
99impl<T> IndexMut<RangeFromExclusive<usize>> for [T] {
100    #[inline]
101    fn index_mut(&mut self, index: RangeFromExclusive<usize>) -> &mut Self::Output {
102        self.index_mut(index.into_range_from())
103    }
104}
105
106#[cfg(feature = "alloc")]
107#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
108impl<T> Index<RangeFromExclusive<usize>> for Vec<T> {
109    type Output = <Vec<T> as Index<RangeFrom<usize>>>::Output;
110
111    #[inline]
112    fn index(&self, index: RangeFromExclusive<usize>) -> &Self::Output {
113        self.index(index.into_range_from())
114    }
115}
116
117#[cfg(feature = "alloc")]
118#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
119impl<T> IndexMut<RangeFromExclusive<usize>> for Vec<T> {
120    #[inline]
121    fn index_mut(&mut self, index: RangeFromExclusive<usize>) -> &mut Self::Output {
122        self.index_mut(index.into_range_from())
123    }
124}
125
126impl Index<RangeFromExclusive<usize>> for str {
127    type Output = <str as Index<RangeFrom<usize>>>::Output;
128
129    #[inline]
130    fn index(&self, index: RangeFromExclusive<usize>) -> &Self::Output {
131        self.index(index.into_range_from())
132    }
133}
134
135impl IndexMut<RangeFromExclusive<usize>> for str {
136    #[inline]
137    fn index_mut(&mut self, index: RangeFromExclusive<usize>) -> &mut Self::Output {
138        self.index_mut(index.into_range_from())
139    }
140}
141
142#[cfg(feature = "alloc")]
143#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
144impl Index<RangeFromExclusive<usize>> for String {
145    type Output = <String as Index<RangeFrom<usize>>>::Output;
146
147    #[inline]
148    fn index(&self, index: RangeFromExclusive<usize>) -> &Self::Output {
149        self.index(index.into_range_from())
150    }
151}
152
153#[cfg(feature = "alloc")]
154#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
155impl IndexMut<RangeFromExclusive<usize>> for String {
156    #[inline]
157    fn index_mut(&mut self, index: RangeFromExclusive<usize>) -> &mut Self::Output {
158        self.index_mut(index.into_range_from())
159    }
160}
161
162impl Index<RangeFromExclusive<usize>> for CStr {
163    type Output = <CStr as Index<RangeFrom<usize>>>::Output;
164
165    #[inline]
166    fn index(&self, index: RangeFromExclusive<usize>) -> &Self::Output {
167        self.index(index.into_range_from())
168    }
169}
170
171#[cfg(feature = "serde")]
172#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
173impl<T> Serialize for RangeFromExclusive<T>
174where
175    T: Serialize,
176{
177    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
178    where
179        S: Serializer,
180    {
181        let mut state = serializer.serialize_struct("RangeFromExclusive", 1)?;
182        state.serialize_field("start", &self.start)?;
183        state.end()
184    }
185}
186
187#[cfg(feature = "serde")]
188#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
189impl<'de, T> Deserialize<'de> for RangeFromExclusive<T>
190where
191    T: Deserialize<'de>,
192{
193    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
194    where
195        D: Deserializer<'de>,
196    {
197        const FIELDS: &[&str] = &["start"];
198
199        enum Field {
200            Start,
201        }
202
203        impl<'de> Deserialize<'de> for Field {
204            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
205            where
206                D: Deserializer<'de>,
207            {
208                struct FieldVisitor;
209
210                impl<'de> Visitor<'de> for FieldVisitor {
211                    type Value = Field;
212
213                    fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
214                        formatter.write_str("`start`")
215                    }
216
217                    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
218                    where
219                        E: de::Error,
220                    {
221                        match value {
222                            "start" => Ok(Field::Start),
223                            _ => Err(E::unknown_field(value, FIELDS)),
224                        }
225                    }
226
227                    fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
228                    where
229                        E: de::Error,
230                    {
231                        match value {
232                            b"start" => Ok(Field::Start),
233                            _ => Err(E::unknown_field(string::from_utf8_lossy(value), FIELDS)),
234                        }
235                    }
236                }
237
238                deserializer.deserialize_identifier(FieldVisitor)
239            }
240        }
241
242        struct RangeFromExclusiveVisitor<T> {
243            marker: PhantomData<T>,
244        }
245
246        impl<'de, T> Visitor<'de> for RangeFromExclusiveVisitor<T>
247        where
248            T: Deserialize<'de>,
249        {
250            type Value = RangeFromExclusive<T>;
251
252            fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
253                formatter.write_str("struct RangeFromExclusive")
254            }
255
256            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
257            where
258                A: SeqAccess<'de>,
259            {
260                let start = seq
261                    .next_element()?
262                    .ok_or_else(|| A::Error::invalid_length(0, &self))?;
263                Ok(RangeFromExclusive { start })
264            }
265
266            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
267            where
268                A: MapAccess<'de>,
269            {
270                let mut start = None;
271
272                while let Some(field) = map.next_key()? {
273                    match field {
274                        Field::Start => {
275                            if start.is_some() {
276                                return Err(A::Error::duplicate_field("start"));
277                            }
278                            start = Some(map.next_value()?);
279                        }
280                    }
281                }
282
283                Ok(RangeFromExclusive {
284                    start: start.ok_or_else(|| A::Error::missing_field("start"))?,
285                })
286            }
287        }
288
289        deserializer.deserialize_struct(
290            "RangeFromExclusive",
291            FIELDS,
292            RangeFromExclusiveVisitor {
293                marker: PhantomData,
294            },
295        )
296    }
297}
298
299impl<T> IntoIterator for RangeFromExclusive<T>
300where
301    RangeFrom<T>: Iterator<Item = T>,
302{
303    type IntoIter = IterRangeFromExclusive<T>;
304    type Item = T;
305
306    fn into_iter(self) -> Self::IntoIter {
307        IterRangeFromExclusive {
308            inner: self.into_range_from(),
309        }
310    }
311}
312
313/// Iterator for [`RangeFromExclusive`].
314pub struct IterRangeFromExclusive<T> {
315    inner: RangeFrom<T>,
316}
317
318impl<T> Iterator for IterRangeFromExclusive<T>
319where
320    RangeFrom<T>: Iterator<Item = T>,
321{
322    type Item = T;
323
324    #[inline]
325    fn next(&mut self) -> Option<Self::Item> {
326        self.inner.next()
327    }
328
329    #[inline]
330    fn size_hint(&self) -> (usize, Option<usize>) {
331        self.inner.size_hint()
332    }
333
334    #[inline]
335    fn nth(&mut self, n: usize) -> Option<Self::Item> {
336        self.inner.nth(n)
337    }
338}
339
340impl<T> FusedIterator for IterRangeFromExclusive<T> where RangeFrom<T>: Iterator<Item = T> {}
341
342#[cfg(test)]
343mod tests {
344    use super::RangeFromExclusive;
345    #[cfg(feature = "alloc")]
346    use alloc::{borrow::ToOwned, vec};
347    #[cfg(all(feature = "alloc", feature = "serde"))]
348    use claims::{assert_err_eq, assert_ok_eq};
349    use claims::{assert_matches, assert_ok, assert_some_eq};
350    use core::{
351        ffi::CStr,
352        ops::{
353            Bound::{Excluded, Unbounded},
354            RangeBounds,
355        },
356    };
357    #[cfg(all(feature = "alloc", feature = "serde"))]
358    use serde_assert::{de, Deserializer, Serializer, Token};
359    #[cfg(all(feature = "alloc", feature = "serde"))]
360    use serde_core::{Deserialize, Serialize};
361
362    #[test]
363    fn range_bounds() {
364        let range = RangeFromExclusive { start: 1 };
365
366        assert_matches!(range.start_bound(), Excluded(1));
367        assert_matches!(range.end_bound(), Unbounded);
368    }
369
370    #[test]
371    fn range_bounds_borrowed() {
372        let range = RangeFromExclusive { start: &1 };
373
374        assert_matches!(RangeBounds::<usize>::start_bound(&range), Excluded(1));
375        assert_matches!(RangeBounds::<usize>::end_bound(&range), Unbounded);
376    }
377
378    #[test]
379    fn index_slice() {
380        let range = RangeFromExclusive { start: 1 };
381        let slice = [0, 1, 2, 3];
382
383        assert_eq!(slice[range], [2, 3]);
384    }
385
386    #[cfg(feature = "alloc")]
387    #[test]
388    fn index_vec() {
389        let range = RangeFromExclusive { start: 1 };
390        let vec = vec![0, 1, 2, 3];
391
392        assert_eq!(vec[range], [2, 3]);
393    }
394
395    #[test]
396    fn index_str() {
397        let range = RangeFromExclusive { start: 1 };
398        let str = "abcd";
399
400        assert_eq!(&str[range], "cd");
401    }
402
403    #[cfg(feature = "alloc")]
404    #[test]
405    fn index_string() {
406        let range = RangeFromExclusive { start: 1 };
407        let string = "abcd".to_owned();
408
409        assert_eq!(&string[range], "cd");
410    }
411
412    #[test]
413    fn index_mut_slice() {
414        let range = RangeFromExclusive { start: 1 };
415        let mut slice = [0, 1, 2, 3];
416
417        slice[range][0] = 4;
418        slice[range][1] = 5;
419
420        assert_eq!(slice, [0, 1, 4, 5]);
421    }
422
423    #[cfg(feature = "alloc")]
424    #[test]
425    fn index_mut_vec() {
426        let range = RangeFromExclusive { start: 1 };
427        let mut vec = vec![0, 1, 2, 3];
428
429        vec[range][0] = 4;
430        vec[range][1] = 5;
431
432        assert_eq!(vec, [0, 1, 4, 5]);
433    }
434
435    #[cfg(feature = "alloc")]
436    #[test]
437    fn index_mut_str() {
438        let range = RangeFromExclusive { start: 1 };
439        let mut string = "abcd".to_owned();
440        let str: &mut str = string.as_mut_str();
441
442        str[range].make_ascii_uppercase();
443
444        assert_eq!(string, "abCD");
445    }
446
447    #[cfg(feature = "alloc")]
448    #[test]
449    fn index_mut_string() {
450        let range = RangeFromExclusive { start: 1 };
451        let mut string = "abcd".to_owned();
452
453        string[range].make_ascii_uppercase();
454
455        assert_eq!(string, "abCD");
456    }
457
458    #[test]
459    fn index_cstr() {
460        let range = RangeFromExclusive { start: 1 };
461        let str = assert_ok!(CStr::from_bytes_with_nul(b"abcd\x00"));
462
463        assert_eq!(&str[range].to_bytes(), b"cd");
464    }
465
466    #[test]
467    fn iter_next() {
468        let range = RangeFromExclusive { start: 1 };
469        let mut iter = range.into_iter();
470
471        assert_some_eq!(iter.next(), 2);
472        assert_some_eq!(iter.next(), 3);
473    }
474
475    #[test]
476    fn iter_size_hint() {
477        let range = RangeFromExclusive { start: 1 };
478        let iter = range.into_iter();
479
480        assert_eq!(iter.size_hint(), (usize::MAX, None));
481    }
482
483    #[test]
484    fn iter_nth() {
485        let range = RangeFromExclusive { start: 1 };
486        let mut iter = range.into_iter();
487
488        assert_some_eq!(iter.nth(42), 44);
489        assert_some_eq!(iter.nth(100), 145);
490    }
491
492    #[cfg(all(feature = "alloc", feature = "serde"))]
493    #[test]
494    fn serialize() {
495        let range = RangeFromExclusive { start: 1u32 };
496
497        let serializer = Serializer::builder().build();
498        assert_ok_eq!(
499            range.serialize(&serializer),
500            [
501                Token::Struct {
502                    name: "RangeFromExclusive",
503                    len: 1
504                },
505                Token::Field("start"),
506                Token::U32(1),
507                Token::StructEnd,
508            ]
509        );
510    }
511
512    #[cfg(all(feature = "alloc", feature = "serde"))]
513    #[test]
514    fn deserialize() {
515        let mut deserializer = Deserializer::builder([
516            Token::Struct {
517                name: "RangeFromExclusive",
518                len: 1,
519            },
520            Token::Field("start"),
521            Token::I8(-5),
522            Token::StructEnd,
523        ])
524        .build();
525
526        assert_ok_eq!(
527            RangeFromExclusive::deserialize(&mut deserializer),
528            RangeFromExclusive { start: -5i8 }
529        );
530    }
531
532    #[cfg(all(feature = "alloc", feature = "serde"))]
533    #[test]
534    fn deserialize_unknown_field() {
535        let mut deserializer = Deserializer::builder([
536            Token::Struct {
537                name: "RangeFromExclusive",
538                len: 1,
539            },
540            Token::Field("invalid"),
541            Token::I8(-5),
542            Token::StructEnd,
543        ])
544        .build();
545
546        assert_err_eq!(
547            RangeFromExclusive::<i8>::deserialize(&mut deserializer),
548            de::Error::UnknownField("invalid".to_owned(), &["start"])
549        );
550    }
551
552    #[cfg(all(feature = "alloc", feature = "serde"))]
553    #[test]
554    fn deserialize_duplicate_field() {
555        let mut deserializer = Deserializer::builder([
556            Token::Struct {
557                name: "RangeFromExclusive",
558                len: 2,
559            },
560            Token::Field("start"),
561            Token::I8(-5),
562            Token::Field("start"),
563            Token::I8(42),
564            Token::StructEnd,
565        ])
566        .build();
567
568        assert_err_eq!(
569            RangeFromExclusive::<i8>::deserialize(&mut deserializer),
570            de::Error::DuplicateField("start")
571        );
572    }
573
574    #[cfg(all(feature = "alloc", feature = "serde"))]
575    #[test]
576    fn deserialize_missing_field() {
577        let mut deserializer = Deserializer::builder([
578            Token::Struct {
579                name: "RangeFromExclusive",
580                len: 0,
581            },
582            Token::StructEnd,
583        ])
584        .build();
585
586        assert_err_eq!(
587            RangeFromExclusive::<i8>::deserialize(&mut deserializer),
588            de::Error::MissingField("start")
589        );
590    }
591
592    #[cfg(all(feature = "alloc", feature = "serde"))]
593    #[test]
594    fn serde_roundtrip() {
595        let range = RangeFromExclusive { start: 1u32 };
596
597        let serializer = Serializer::builder().build();
598        let mut deserializer =
599            Deserializer::builder(assert_ok!(range.serialize(&serializer))).build();
600        assert_ok_eq!(RangeFromExclusive::deserialize(&mut deserializer), range);
601    }
602}