1 | /// A range bounded inclusively for counting parses performed |
2 | /// |
3 | /// This is flexible in what can be converted to a [Range]: |
4 | /// ```rust |
5 | /// # #[cfg (feature = "std" )] { |
6 | /// # use winnow::prelude::*; |
7 | /// # use winnow::token::any; |
8 | /// # use winnow::combinator::repeat; |
9 | /// # fn inner(input: &mut &str) -> ModalResult<char> { |
10 | /// # any.parse_next(input) |
11 | /// # } |
12 | /// # let mut input = "0123456789012345678901234567890123456789" ; |
13 | /// # let input = &mut input; |
14 | /// let parser: Vec<_> = repeat(5, inner).parse_next(input).unwrap(); |
15 | /// # let mut input = "0123456789012345678901234567890123456789" ; |
16 | /// # let input = &mut input; |
17 | /// let parser: Vec<_> = repeat(.., inner).parse_next(input).unwrap(); |
18 | /// # let mut input = "0123456789012345678901234567890123456789" ; |
19 | /// # let input = &mut input; |
20 | /// let parser: Vec<_> = repeat(1.., inner).parse_next(input).unwrap(); |
21 | /// # let mut input = "0123456789012345678901234567890123456789" ; |
22 | /// # let input = &mut input; |
23 | /// let parser: Vec<_> = repeat(5..8, inner).parse_next(input).unwrap(); |
24 | /// # let mut input = "0123456789012345678901234567890123456789" ; |
25 | /// # let input = &mut input; |
26 | /// let parser: Vec<_> = repeat(5..=8, inner).parse_next(input).unwrap(); |
27 | /// # } |
28 | /// ``` |
29 | #[derive (PartialEq, Eq, Copy, Clone)] |
30 | pub struct Range { |
31 | pub(crate) start_inclusive: usize, |
32 | pub(crate) end_inclusive: Option<usize>, |
33 | } |
34 | |
35 | impl Range { |
36 | #[inline (always)] |
37 | fn raw(start_inclusive: usize, end_inclusive: Option<usize>) -> Self { |
38 | Self { |
39 | start_inclusive, |
40 | end_inclusive, |
41 | } |
42 | } |
43 | } |
44 | |
45 | impl crate::lib::std::ops::RangeBounds<usize> for Range { |
46 | #[inline (always)] |
47 | fn start_bound(&self) -> crate::lib::std::ops::Bound<&usize> { |
48 | crate::lib::std::ops::Bound::Included(&self.start_inclusive) |
49 | } |
50 | |
51 | #[inline (always)] |
52 | fn end_bound(&self) -> crate::lib::std::ops::Bound<&usize> { |
53 | if let Some(end_inclusive: &usize) = &self.end_inclusive { |
54 | crate::lib::std::ops::Bound::Included(end_inclusive) |
55 | } else { |
56 | crate::lib::std::ops::Bound::Unbounded |
57 | } |
58 | } |
59 | } |
60 | |
61 | impl From<usize> for Range { |
62 | #[inline (always)] |
63 | fn from(fixed: usize) -> Self { |
64 | (fixed..=fixed).into() |
65 | } |
66 | } |
67 | |
68 | impl From<crate::lib::std::ops::Range<usize>> for Range { |
69 | #[inline (always)] |
70 | fn from(range: crate::lib::std::ops::Range<usize>) -> Self { |
71 | let start_inclusive: usize = range.start; |
72 | let end_inclusive: Option = Some(range.end.saturating_sub(1)); |
73 | Self::raw(start_inclusive, end_inclusive) |
74 | } |
75 | } |
76 | |
77 | impl From<crate::lib::std::ops::RangeFull> for Range { |
78 | #[inline (always)] |
79 | fn from(_: crate::lib::std::ops::RangeFull) -> Self { |
80 | let start_inclusive: usize = 0; |
81 | let end_inclusive: Option = None; |
82 | Self::raw(start_inclusive, end_inclusive) |
83 | } |
84 | } |
85 | |
86 | impl From<crate::lib::std::ops::RangeFrom<usize>> for Range { |
87 | #[inline (always)] |
88 | fn from(range: crate::lib::std::ops::RangeFrom<usize>) -> Self { |
89 | let start_inclusive: usize = range.start; |
90 | let end_inclusive: Option = None; |
91 | Self::raw(start_inclusive, end_inclusive) |
92 | } |
93 | } |
94 | |
95 | impl From<crate::lib::std::ops::RangeTo<usize>> for Range { |
96 | #[inline (always)] |
97 | fn from(range: crate::lib::std::ops::RangeTo<usize>) -> Self { |
98 | let start_inclusive: usize = 0; |
99 | let end_inclusive: Option = Some(range.end.saturating_sub(1)); |
100 | Self::raw(start_inclusive, end_inclusive) |
101 | } |
102 | } |
103 | |
104 | impl From<crate::lib::std::ops::RangeInclusive<usize>> for Range { |
105 | #[inline (always)] |
106 | fn from(range: crate::lib::std::ops::RangeInclusive<usize>) -> Self { |
107 | let start_inclusive: usize = *range.start(); |
108 | let end_inclusive: Option = Some(*range.end()); |
109 | Self::raw(start_inclusive, end_inclusive) |
110 | } |
111 | } |
112 | |
113 | impl From<crate::lib::std::ops::RangeToInclusive<usize>> for Range { |
114 | #[inline (always)] |
115 | fn from(range: crate::lib::std::ops::RangeToInclusive<usize>) -> Self { |
116 | let start_inclusive: usize = 0; |
117 | let end_inclusive: Option = Some(range.end); |
118 | Self::raw(start_inclusive, end_inclusive) |
119 | } |
120 | } |
121 | |
122 | impl crate::lib::std::fmt::Display for Range { |
123 | fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result { |
124 | self.start_inclusive.fmt(f)?; |
125 | match self.end_inclusive { |
126 | Some(e: usize) if e == self.start_inclusive => {} |
127 | Some(e: usize) => { |
128 | "..=" .fmt(f)?; |
129 | e.fmt(f)?; |
130 | } |
131 | None => { |
132 | ".." .fmt(f)?; |
133 | } |
134 | } |
135 | Ok(()) |
136 | } |
137 | } |
138 | |
139 | impl crate::lib::std::fmt::Debug for Range { |
140 | fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result { |
141 | write!(f, " {self}" ) |
142 | } |
143 | } |
144 | |