1use std::ops::{Bound, RangeBounds};
2
3pub trait AltError<I> {
5 fn alt(self, other: Self, at: I) -> Self;
6}
7
8impl<I> AltError<I> for () {
9 fn alt(self, _: (), _: I) { }
10}
11
12pub trait Tag<I> {
14 type Output;
15
16 fn parse_tag(&self, inp: I) -> Option<(Self::Output, I)>;
18}
19
20impl<'a> Tag<&'a str> for str {
21 type Output = &'a str;
22
23 fn parse_tag(&self, inp: &'a str) -> Option<(&'a str, &'a str)> {
24 if inp.starts_with(self) {
25 Some(inp.split_at(self.len()))
26 } else {
27 None
28 }
29 }
30}
31
32impl<'a, T> Tag<&'a [T]> for [T] where T: PartialEq {
33 type Output = &'a [T];
34
35 fn parse_tag(&self, inp: &'a [T]) -> Option<(&'a [T], &'a [T])> {
36 if inp.starts_with(self) {
37 Some(inp.split_at(self.len()))
38 } else {
39 None
40 }
41 }
42}
43
44impl<'a> Tag<&'a [u8]> for str {
45 type Output = &'a [u8];
46
47 fn parse_tag(&self, inp: &'a [u8]) -> Option<(&'a [u8], &'a [u8])> {
48 self.as_bytes().parse_tag(inp)
49 }
50}
51
52pub trait TagError<'a, T: ?Sized, I> {
54 fn tag(tag: &'a T, at: I) -> Self;
55}
56
57impl<'a, I, T: ?Sized> TagError<'a, T, I> for () {
58 fn tag(_: &'a T, _: I) { }
59}
60
61pub trait RangeLike {
66 fn can_continue(&self, n: usize) -> bool;
67 fn has_to_continue(&self, n: usize) -> bool;
68
69 fn capacity(&self) -> usize {
71 0
72 }
73}
74
75fn continue_from_bound(n: usize, bound: Bound<&usize>, unbounded: bool) -> bool {
76 match bound {
77 Bound::Included(&stop) => n < stop,
78 Bound::Excluded(&stop) => n + 1 < stop,
79 Bound::Unbounded => unbounded,
80 }
81}
82
83impl<T> RangeLike for T where T: RangeBounds<usize> {
84 fn can_continue(&self, n: usize) -> bool {
85 continue_from_bound(n, self.end_bound(), true)
86 }
87
88 fn has_to_continue(&self, n: usize) -> bool {
89 continue_from_bound(n, self.start_bound(), false)
90 }
91
92 fn capacity(&self) -> usize {
93 match self.end_bound() {
94 Bound::Included(&n) => n,
95 Bound::Excluded(&n) => n.saturating_sub(1),
96 Bound::Unbounded => match self.start_bound() {
97 Bound::Included(&n) => n,
98 Bound::Excluded(&n) => n + 1,
99 Bound::Unbounded => 0,
100 }
101 }
102 }
103}
104
105pub trait Collection {
107 type Item;
108
109 fn reserve(&mut self, additional: usize);
110 fn push(&mut self, index: usize, item: Self::Item);
111}
112
113impl<T> Collection for Vec<T> {
114 type Item = T;
115
116 fn reserve(&mut self, additional: usize) {
117 self.reserve(additional);
118 }
119
120 fn push(&mut self, _: usize, item: Self::Item) {
121 self.push(item);
122 }
123}
124
125impl Collection for String {
126 type Item = char;
127
128 fn reserve(&mut self, additional: usize) {
129 self.reserve(additional);
130 }
131
132 fn push(&mut self, _: usize, item: Self::Item) {
133 self.push(item);
134 }
135}
136
137impl<T> Collection for Option<T> {
138 type Item = T;
139
140 fn reserve(&mut self, additional: usize) {
141 assert!(additional <= 1);
142 }
143
144 fn push(&mut self, _: usize, item: Self::Item) {
145 *self = Some(item);
146 }
147}
148
149macro_rules! collection_impl {
150 ($($n:literal)*) => {
151 $(
152 impl<T> Collection for [T;$n] where T: Default {
153 type Item = T;
154
155 fn reserve(&mut self, additional: usize) {
156 assert!(additional <= $n);
157 }
158
159 fn push(&mut self, index: usize, item: Self::Item) {
160 self[index] = item;
161 }
162 }
163 )*
164 };
165}
166
167collection_impl!(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32);
168
169pub trait HasEof {
171 fn at_eof(&self) -> bool;
172}
173
174impl<'a> HasEof for &'a str {
175 fn at_eof(&self) -> bool {
176 self.is_empty()
177 }
178}
179
180impl<'a, T> HasEof for &'a [T] {
181 fn at_eof(&self) -> bool {
182 self.is_empty()
183 }
184}
185
186pub trait EofError<I> {
188 fn no_eof(at: I) -> Self;
189}
190
191impl<I> EofError<I> for () {
192 fn no_eof(_: I) { }
193}
194
195pub trait NotError<O, I> {
197 fn not(out: O, at: I) -> Self;
198}
199
200impl<O, I> NotError<O, I> for () {
201 fn not(_: O, _: I) { }
202}
203
204pub trait Recordable {
206 type Output;
207
208 fn record(self, later: Self) -> Self::Output;
209}
210
211impl<'a> Recordable for &'a str {
212 type Output = &'a str;
213
214 fn record(self, later: &'a str) -> &'a str {
215 &self[..(self.len() - later.len())]
216 }
217}
218
219impl<'a, T> Recordable for &'a [T] {
220 type Output = &'a [T];
221
222 fn record(self, later: &'a [T]) -> &'a [T] {
223 &self[..(self.len() - later.len())]
224 }
225}
226
227pub trait SplitFirst: Sized {
229 type Element;
230
231 fn split_first(self) -> Option<(Self::Element, Self)>;
232}
233
234impl<'a> SplitFirst for &'a str {
235 type Element = char;
236
237 fn split_first(self) -> Option<(char, &'a str)> {
238 self.chars().next().map(|c| (c, &self[c.len_utf8()..]))
239 }
240}
241
242impl<'a, T> SplitFirst for &'a [T] {
243 type Element = &'a T;
244
245 fn split_first(self) -> Option<(&'a T, &'a [T])> {
246 self.iter().next().map(|x| (x, &self[1..]))
247 }
248}
249
250pub trait ConsumeError<I: SplitFirst> {
252 fn eof(at: I) -> Self;
253 fn condition_failed(element: I::Element, at: I) -> Self;
254}
255
256impl<I: SplitFirst> ConsumeError<I> for () {
257 fn eof(_: I) { }
258 fn condition_failed(_: I::Element, _: I) { }
259}
260
261pub trait Position<I>: Default {
263 fn record_difference(&self, old: &I, new: &I) -> Self;
264}