aoc/
parse.rs

1use std::{fmt, marker::PhantomData, str::FromStr};
2
3/// Provides methods on `&str` for parsing.
4///
5/// Everything is expected to succeed, so many of this trait's methods will panic on failure.
6///
7/// `T: FromStrUnwrap` requires `T: FromStr, <T as FromStr>::Err: Debug`.
8pub trait Parse {
9    fn parse_uw<T: FromStrUnwrap>(&self) -> T;
10    fn idx(&self, index: usize) -> u8;
11    fn ints_iter<T: FromStrUnwrap>(&self) -> Ints<T>;
12    fn ints<const N: usize, T: FromStrUnwrap>(&self) -> [T; N];
13    fn uints_iter<T: FromStrUnwrap>(&self) -> UInts<T>;
14    fn uints<const N: usize, T: FromStrUnwrap>(&self) -> [T; N];
15    fn try_between(&self, pre: &str, post: &str) -> Option<&str>;
16    // fn try_between_many(&self, pre: &str, post: &[&str]) -> Option<&str>;
17    fn as_parser(&self) -> Parser;
18}
19
20impl Parse for str {
21    /// Short for `.parse::<T>().unwrap()`.
22    ///
23    /// Requires that `T: FromStr` and `<T as FromStr>::Err: Debug`.
24    ///
25    /// # Examples
26    /// ```
27    /// use aoc::Parse;
28    ///
29    /// let s = "-205";
30    ///
31    /// assert_eq!(s.parse_uw::<i32>(), -205);
32    /// ```
33    #[inline]
34    #[track_caller]
35    fn parse_uw<T: FromStrUnwrap>(&self) -> T {
36        T::parse(self)
37    }
38
39    /// Returns the byte at the given index of `self`.
40    ///
41    /// Useful when `self` is an ASCII string slice.
42    ///
43    /// Panics when the index is at least the length of `self`.
44    ///
45    /// # Examples
46    /// ```
47    /// use aoc::Parse;
48    ///
49    /// let s = "hello, world!";
50    ///
51    /// assert_eq!(s.idx(0), b'h');
52    /// assert_eq!(s.idx(7), b'w');
53    /// ```
54    #[inline]
55    #[track_caller]
56    fn idx(&self, index: usize) -> u8 {
57        self.as_bytes()[index]
58    }
59
60    /// Returns an iterator over the signed integers in `self`, parsed into type `T`.
61    ///
62    /// Examples of signed integers include `"1"`, `"-2"` and `"+3"`, but not `"++4"`, `"-+5"` or `"--6"`.
63    /// In the latter cases, all but the last sign will be ignored.
64    ///
65    /// `T` should generally be a signed integer type like `i32`. `T: FromStr` and `<T as FromStr>::Err: Debug` are required.
66    ///
67    /// The returned iterator will panic if it fails to parse an integer into `T`.
68    ///
69    /// # Examples
70    /// ```
71    /// use aoc::Parse;
72    ///
73    /// let s = "some signed integers: 15, -302 and +45.";
74    /// let mut ints = s.ints_iter::<i32>();
75    ///
76    /// assert_eq!(ints.next(), Some(15));
77    /// assert_eq!(ints.next(), Some(-302));
78    /// assert_eq!(ints.next(), Some(45));
79    /// assert_eq!(ints.next(), None);
80    /// ```
81    fn ints_iter<T: FromStrUnwrap>(&self) -> Ints<T> {
82        Ints {
83            s: self,
84            _phantom: PhantomData,
85        }
86    }
87
88    /// Returns an array of the first `N` signed integers in `self`, parsed into type `T`.
89    ///
90    /// Short for `.ints_iter::<T>().collect_n::<N>()`.
91    ///
92    /// Examples of signed integers include `"1"`, `"-2"` and `"+3"`, but not `"++4"`, `"-+5"` or `"--6"`.
93    /// In the latter cases, all but the last sign will be ignored.
94    ///
95    /// `T` should generally be a signed integer type like `i32`. `T: FromStr` and `<T as FromStr>::Err: Debug` are required.
96    ///
97    /// Panics if the iterator yields less than `N` items, or if it fails to parse an integer into `T`.
98    ///
99    /// # Examples
100    /// ```
101    /// use aoc::Parse;
102    ///
103    /// let s = "some signed integers: 15, -302 and +45.";
104    ///
105    /// assert_eq!(s.ints::<3, i32>(), [15, -302, 45]);
106    /// ```
107    #[inline]
108    #[track_caller]
109    fn ints<const N: usize, T: FromStrUnwrap>(&self) -> [T; N] {
110        self.ints_iter().collect_n()
111    }
112
113    /// Returns an iterator over the unsigned integers in `self`, parsed into `T`.
114    ///
115    /// Examples of unsigned integers include `"1"` and `"2"`, but not `"-3"` or `"+4"`.
116    /// In the latter cases, the signs will be ignored.
117    ///
118    /// `T` should generally be an integer type like `u32`. `T: FromStr` and `<T as FromStr>::Err: Debug` are required.
119    ///
120    /// The returned iterator will panic if it fails to parse an integer into `T`.
121    ///
122    /// # Examples
123    /// ```
124    /// use aoc::Parse;
125    ///
126    /// let s = "some unsigned integers: 15, 302 and 45.";
127    /// let mut ints = s.uints_iter::<u32>();
128    ///
129    /// assert_eq!(ints.next(), Some(15));
130    /// assert_eq!(ints.next(), Some(302));
131    /// assert_eq!(ints.next(), Some(45));
132    /// assert_eq!(ints.next(), None);
133    /// ```
134    fn uints_iter<T: FromStrUnwrap>(&self) -> UInts<T> {
135        UInts {
136            s: self,
137            _phantom: PhantomData,
138        }
139    }
140
141    /// Returns an array of the first `N` unsigned integers in `self`, parsed into `T`.
142    ///
143    /// Short for `.uints_iter::<T>().collect_n::<N>()`.
144    ///
145    /// Examples of unsigned integers include `"1"` and `"2"`, but not `"-3"` or `"+4"`.
146    /// In the latter cases, the signs will be ignored.
147    ///
148    /// `T` should generally be an integer type like `u32`. `T: FromStr` and `<T as FromStr>::Err: Debug` are required.
149    ///
150    /// Panics if the iterator yields less than `N` items, or if it fails to parse an integer into `T`.
151    ///
152    /// # Examples
153    /// ```
154    /// use aoc::Parse;
155    ///
156    /// let s = "some unsigned integers: 15, 302 and 45.";
157    ///
158    /// assert_eq!(s.uints::<3, u32>(), [15, 302, 45]);
159    /// ```
160    #[inline]
161    #[track_caller]
162    fn uints<const N: usize, T: FromStrUnwrap>(&self) -> [T; N] {
163        self.uints_iter().collect_n()
164    }
165
166    /// Returns the string slice between `pre` and `post` in `self`.
167    ///
168    /// More specifically, finds the first occurrence of `pre` in `self`, or returns `None` if it does not occur.
169    /// Then, finds the first occurrence of `post` after that, and returns the string slice between the two.
170    /// If `post` does not occur after `pre`, returns the string slice starting after `pre` until the end of `self`.
171    ///
172    /// # Examples
173    /// ```
174    /// use aoc::Parse;
175    ///
176    /// let s = "ecl:gry pid:860033327 eyr:2020";
177    ///
178    /// assert_eq!(s.try_between("ecl:", " "), Some("gry"));
179    /// assert_eq!(s.try_between("pid:", " "), Some("860033327"));
180    /// assert_eq!(s.try_between("eyr:", " "), Some("2020"));
181    /// assert_eq!(s.try_between("cid:", " "), None);
182    /// ```
183    fn try_between(&self, pre: &str, post: &str) -> Option<&str> {
184        let start = self.find(pre)? + pre.len();
185        let rest = &self[start..];
186        let end = rest.find(post).unwrap_or(rest.len()) + start;
187        Some(&self[start..end])
188    }
189
190    // /// Returns the string slice between `pre` and the first occurrence of an element of `post` in `self`.
191    // ///
192    // /// More specifically, finds the first occurrence of `pre` in `self`, or returns `None` if it does not occur.
193    // /// Then, finds the first occurrence of each element of `post` after that, chooses the one that occurs first in `self`,
194    // /// and returns the string slice between `pre` and the chosen element of `post`.
195    // /// If no elements of `post` occur after `pre`, or if `pre` is empty, returns the string slice starting after `pre` until the end of `self`.
196    // ///
197    // /// If `pre` has only one element, this works the same as `Parse::between()`.
198    // ///
199    // /// # Examples
200    // /// ```
201    // /// use aoc::Parse;
202    // ///
203    // /// let s = "ecl:gry pid:860033327,eyr:2020";
204    // ///
205    // /// assert_eq!(s.try_between_many("ecl:", &[" ", ","]), Some("gry"));
206    // /// assert_eq!(s.try_between_many("pid:", &[" ", ","]), Some("860033327"));
207    // /// assert_eq!(s.try_between_many("eyr:", &[" ", ","]), Some("2020"));
208    // /// assert_eq!(s.try_between_many("cid:", &[" ", ","]), None);
209    // /// ```
210    // fn try_between_many(&self, pre: &str, post: &[&str]) -> Option<&str> {
211    //     let start = self.find(pre)? + pre.len();
212    //     let rest = &self[start..];
213    //     let mut end = self.len();
214    //     for &post in post {
215    //         if let Some(i) = rest.find(post) {
216    //             end = end.min(i + start);
217    //         }
218    //     }
219    //     Some(&self[start..end])
220    // }
221
222    /// Returns a struct for gradually parsing data from `self` from left to right.
223    ///
224    /// Each time a method is called on the struct, the processed portion of the string is "consumed",
225    /// and future method calls will only consider the remainder of the string.
226    ///
227    /// # Examples
228    /// ```
229    /// use aoc::Parse;
230    ///
231    /// let s = "move 10 from 271 to 3";
232    /// let mut parser = s.as_parser();
233    ///
234    /// assert_eq!(parser.between(" ", " "), "10");
235    /// assert_eq!(parser.between(" ", " "), "271");
236    /// assert_eq!(parser.after(" "), "3");
237    /// ```
238    /// Another way to do the same thing is:
239    /// ```
240    /// use aoc::Parse;
241    ///
242    /// let s = "move 10 from 271 to 3";
243    /// let mut parser = s.as_parser().skip(5);
244    ///
245    /// assert_eq!(parser.before(" "), "10");
246    /// parser.skip(5);
247    /// assert_eq!(parser.before(" "), "271");
248    /// parser.skip(3);
249    /// assert_eq!(parser.rest(), "3");
250    /// ```
251    /// Or alternatively:
252    /// ```
253    /// use aoc::Parse;
254    ///
255    /// let s = "move 10 from 271 to 3";
256    /// let mut parser = s.as_parser();
257    ///
258    /// assert_eq!(parser.between("move ", " "), "10");
259    /// assert_eq!(parser.between("from ", " "), "271");
260    /// assert_eq!(parser.after("to "), "3");
261    /// ```
262    #[inline]
263    fn as_parser(&self) -> Parser {
264        Parser::new(self)
265    }
266}
267
268impl<S> Parse for S
269where
270    S: AsRef<str>,
271{
272    /// Short for `.parse::<T>().unwrap()`.
273    ///
274    /// Requires that `T: FromStr` and `<T as FromStr>::Err: Debug`.
275    ///
276    /// # Examples
277    /// ```
278    /// use aoc::Parse;
279    ///
280    /// let s = "-205";
281    ///
282    /// assert_eq!(s.parse_uw::<i32>(), -205);
283    /// ```
284    fn parse_uw<T: FromStrUnwrap>(&self) -> T {
285        self.as_ref().parse_uw()
286    }
287
288    /// Returns the byte at the given index of `self`.
289    ///
290    /// Useful when `self` is an ASCII string slice.
291    ///
292    /// Panics when the index is at least the length of `self`.
293    ///
294    /// # Examples
295    /// ```
296    /// use aoc::Parse;
297    ///
298    /// let s = "hello, world!";
299    ///
300    /// assert_eq!(s.idx(0), b'h');
301    /// assert_eq!(s.idx(7), b'w');
302    /// ```
303    fn idx(&self, index: usize) -> u8 {
304        self.as_ref().idx(index)
305    }
306
307    /// Returns an iterator over the signed integers in `self`, parsed into type `T`.
308    ///
309    /// Examples of signed integers include `"1"`, `"-2"` and `"+3"`, but not `"++4"`, `"-+5"` or `"--6"`.
310    /// In the latter cases, all but the last sign will be ignored.
311    ///
312    /// `T` should generally be a signed integer type like `i32`. `T: FromStr` and `<T as FromStr>::Err: Debug` are required.
313    ///
314    /// The returned iterator will panic if it fails to parse an integer into `T`.
315    ///
316    /// # Examples
317    /// ```
318    /// use aoc::Parse;
319    ///
320    /// let s = "some signed integers: 15, -302 and +45.";
321    /// let mut ints = s.ints_iter::<i32>();
322    ///
323    /// assert_eq!(ints.next(), Some(15));
324    /// assert_eq!(ints.next(), Some(-302));
325    /// assert_eq!(ints.next(), Some(45));
326    /// assert_eq!(ints.next(), None);
327    /// ```
328    fn ints_iter<T: FromStrUnwrap>(&self) -> Ints<T> {
329        self.as_ref().ints_iter()
330    }
331
332    /// Returns an array of the first `N` signed integers in `self`, parsed into type `T`.
333    ///
334    /// Short for `.ints_iter::<T>().collect_n::<N>()`.
335    ///
336    /// Examples of signed integers include `"1"`, `"-2"` and `"+3"`, but not `"++4"`, `"-+5"` or `"--6"`.
337    /// In the latter cases, all but the last sign will be ignored.
338    ///
339    /// `T` should generally be a signed integer type like `i32`. `T: FromStr` and `<T as FromStr>::Err: Debug` are required.
340    ///
341    /// Panics if the iterator yields less than `N` items, or if it fails to parse an integer into `T`.
342    ///
343    /// # Examples
344    /// ```
345    /// use aoc::Parse;
346    ///
347    /// let s = "some signed integers: 15, -302 and +45.";
348    ///
349    /// assert_eq!(s.ints::<3, i32>(), [15, -302, 45]);
350    /// ```
351    fn ints<const N: usize, T: FromStrUnwrap>(&self) -> [T; N] {
352        self.as_ref().ints()
353    }
354
355    /// Returns an iterator over the unsigned integers in `self`, parsed into `T`.
356    ///
357    /// Examples of unsigned integers include `"1"` and `"2"`, but not `"-3"` or `"+4"`.
358    /// In the latter cases, the signs will be ignored.
359    ///
360    /// `T` should generally be an integer type like `u32`. `T: FromStr` and `<T as FromStr>::Err: Debug` are required.
361    ///
362    /// The returned iterator will panic if it fails to parse an integer into `T`.
363    ///
364    /// # Examples
365    /// ```
366    /// use aoc::Parse;
367    ///
368    /// let s = "some unsigned integers: 15, 302 and 45.";
369    /// let mut ints = s.uints_iter::<u32>();
370    ///
371    /// assert_eq!(ints.next(), Some(15));
372    /// assert_eq!(ints.next(), Some(302));
373    /// assert_eq!(ints.next(), Some(45));
374    /// assert_eq!(ints.next(), None);
375    /// ```
376    fn uints_iter<T: FromStrUnwrap>(&self) -> UInts<T> {
377        self.as_ref().uints_iter()
378    }
379
380    /// Returns an array of the first `N` unsigned integers in `self`, parsed into `T`.
381    ///
382    /// Short for `.uints_iter::<T>().collect_n::<N>()`.
383    ///
384    /// Examples of unsigned integers include `"1"` and `"2"`, but not `"-3"` or `"+4"`.
385    /// In the latter cases, the signs will be ignored.
386    ///
387    /// `T` should generally be an integer type like `u32`. `T: FromStr` and `<T as FromStr>::Err: Debug` are required.
388    ///
389    /// Panics if the iterator yields less than `N` items, or if it fails to parse an integer into `T`.
390    ///
391    /// # Examples
392    /// ```
393    /// use aoc::Parse;
394    ///
395    /// let s = "some unsigned integers: 15, 302 and 45.";
396    ///
397    /// assert_eq!(s.uints::<3, u32>(), [15, 302, 45]);
398    /// ```
399    fn uints<const N: usize, T: FromStrUnwrap>(&self) -> [T; N] {
400        self.as_ref().uints()
401    }
402
403    /// Returns the string slice between `pre` and `post` in `self`.
404    ///
405    /// More specifically, finds the first occurrence of `pre` in `self`, or returns `None` if it does not occur.
406    /// Then, finds the first occurrence of `post` after that, and returns the string slice between the two.
407    /// If `post` does not occur after `pre`, returns the string slice starting after `pre` until the end of `self`.
408    ///
409    /// # Examples
410    /// ```
411    /// use aoc::Parse;
412    ///
413    /// let s = "ecl:gry pid:860033327 eyr:2020";
414    ///
415    /// assert_eq!(s.try_between("ecl:", " "), Some("gry"));
416    /// assert_eq!(s.try_between("pid:", " "), Some("860033327"));
417    /// assert_eq!(s.try_between("eyr:", " "), Some("2020"));
418    /// assert_eq!(s.try_between("cid:", " "), None);
419    /// ```
420    fn try_between(&self, pre: &str, post: &str) -> Option<&str> {
421        self.as_ref().try_between(pre, post)
422    }
423
424    /// Returns a struct for gradually parsing data from `self` from left to right.
425    ///
426    /// Each time a method is called on the struct, the processed portion of the string is "consumed",
427    /// and future method calls will only consider the remainder of the string.
428    ///
429    /// # Examples
430    /// ```
431    /// use aoc::Parse;
432    ///
433    /// let s = "move 10 from 271 to 3";
434    /// let mut parser = s.as_parser();
435    ///
436    /// assert_eq!(parser.between(" ", " "), "10");
437    /// assert_eq!(parser.between(" ", " "), "271");
438    /// assert_eq!(parser.after(" "), "3");
439    /// ```
440    /// Another way to do the same thing is:
441    /// ```
442    /// use aoc::Parse;
443    ///
444    /// let s = "move 10 from 271 to 3";
445    /// let mut parser = s.as_parser().skip(5);
446    ///
447    /// assert_eq!(parser.before(" "), "10");
448    /// parser.skip(5);
449    /// assert_eq!(parser.before(" "), "271");
450    /// parser.skip(3);
451    /// assert_eq!(parser.rest(), "3");
452    /// ```
453    /// Or alternatively:
454    /// ```
455    /// use aoc::Parse;
456    ///
457    /// let s = "move 10 from 271 to 3";
458    /// let mut parser = s.as_parser();
459    ///
460    /// assert_eq!(parser.between("move ", " "), "10");
461    /// assert_eq!(parser.between("from ", " "), "271");
462    /// assert_eq!(parser.after("to "), "3");
463    /// ```
464    fn as_parser(&self) -> Parser {
465        self.as_ref().as_parser()
466    }
467}
468
469pub trait FromStrUnwrap {
470    fn parse(s: &str) -> Self;
471}
472
473impl<T> FromStrUnwrap for T
474where
475    T: FromStr,
476    <T as FromStr>::Err: fmt::Debug,
477{
478    #[inline(always)]
479    #[track_caller]
480    fn parse(s: &str) -> Self {
481        s.parse().unwrap()
482    }
483}
484
485/// An iterator over the signed integers in a `&str`.
486///
487/// Panics if it fails to parse an integer into `T`.
488#[derive(Clone, Copy, Debug)]
489pub struct Ints<'a, T> {
490    s: &'a str,
491    _phantom: PhantomData<T>,
492}
493
494impl<'a, T: FromStrUnwrap> Iterator for Ints<'a, T> {
495    type Item = T;
496
497    #[track_caller]
498    fn next(&mut self) -> Option<Self::Item> {
499        fn is_digit_or_sign(ch: u8) -> bool {
500            ch.is_ascii_digit() || ch == b'-' || ch == b'+'
501        }
502
503        let (s, mut i) = (self.s, 0);
504        loop {
505            while i < s.len() && !is_digit_or_sign(s.idx(i)) {
506                i += 1;
507            }
508            if i >= s.len() {
509                return None;
510            }
511            let mut j = i + 1;
512            while j < s.len() && s.idx(j).is_ascii_digit() {
513                j += 1;
514            }
515            if !s.idx(j - 1).is_ascii_digit() {
516                i = j;
517                continue;
518            }
519            self.s = &s[j..];
520            return Some(s[i..j].parse_uw());
521        }
522    }
523}
524
525/// An iterator over the unsigned integers in a `&str`.
526///
527/// Panics if it fails to parse an integer into `T`.
528#[derive(Clone, Copy, Debug)]
529pub struct UInts<'a, T> {
530    s: &'a str,
531    _phantom: PhantomData<T>,
532}
533
534impl<'a, T: FromStrUnwrap> Iterator for UInts<'a, T> {
535    type Item = T;
536
537    #[track_caller]
538    fn next(&mut self) -> Option<Self::Item> {
539        let (s, mut i) = (self.s, 0);
540        while i < s.len() && !s.idx(i).is_ascii_digit() {
541            i += 1;
542        }
543        if i >= s.len() {
544            return None;
545        }
546        let mut j = i + 1;
547        while j < s.len() && s.idx(j).is_ascii_digit() {
548            j += 1;
549        }
550        self.s = &s[j..];
551        Some(s[i..j].parse_uw())
552    }
553}
554
555/// Provides methods on iterators to reduce allocations and `.unwrap()` calls when success is assumed.
556pub trait IterUnwrap {
557    type Item;
558
559    fn next_uw(&mut self) -> Self::Item;
560    fn collect_n<const N: usize>(&mut self) -> [Self::Item; N];
561}
562
563impl<I> IterUnwrap for I
564where
565    I: Iterator,
566{
567    type Item = <I as Iterator>::Item;
568
569    /// Short for `.next().unwrap()`.
570    ///
571    /// # Examples
572    /// ```
573    /// use aoc::IterUnwrap;
574    ///
575    /// let mut iter = [1, 2, 3].into_iter();
576    ///
577    /// assert_eq!(iter.next_uw(), 1);
578    /// assert_eq!(iter.next_uw(), 2);
579    /// assert_eq!(iter.next_uw(), 3);
580    /// ```
581    #[inline]
582    #[track_caller]
583    fn next_uw(&mut self) -> Self::Item {
584        self.next().unwrap()
585    }
586
587    /// Collects the next `N` items yielded by the iterator into an array.
588    ///
589    /// Panics if the iterator yields less than `N` items.
590    ///
591    /// # Examples
592    /// ```
593    /// use aoc::IterUnwrap;
594    ///
595    /// assert_eq!("hello, world!".chars().collect_n::<5>(), ['h', 'e', 'l', 'l', 'o']);
596    /// ```
597    #[track_caller]
598    fn collect_n<const N: usize>(&mut self) -> [Self::Item; N] {
599        let arr = [(); N].map(|_| self.next());
600        for res in &arr {
601            if res.is_none() {
602                panic!("not enough elements in the iterator to fill the size `N` array")
603            }
604        }
605        arr.map(|x| x.unwrap())
606    }
607}
608
609/// A struct for gradually parsing data from a string from left to right.
610///
611/// Each time a method is called, the processed portion of the string is "consumed",
612/// and future method calls will only consider the remainder of the string.
613///
614/// # Examples
615/// ```
616/// use aoc::Parse;
617///
618/// let s = "move 10 from 271 to 3";
619/// let mut parser = s.as_parser();
620///
621/// assert_eq!(parser.between(" ", " "), "10");
622/// assert_eq!(parser.between(" ", " "), "271");
623/// assert_eq!(parser.after(" "), "3");
624/// ```
625/// Another way to do the same thing is:
626/// ```
627/// use aoc::Parse;
628///
629/// let s = "move 10 from 271 to 3";
630/// let mut parser = s.as_parser().skip(5);
631///
632/// assert_eq!(parser.before(" "), "10");
633/// parser.skip(5);
634/// assert_eq!(parser.before(" "), "271");
635/// parser.skip(3);
636/// assert_eq!(parser.rest(), "3");
637/// ```
638/// Or alternatively:
639/// ```
640/// use aoc::Parse;
641///
642/// let s = "move 10 from 271 to 3";
643/// let mut parser = s.as_parser();
644///
645/// assert_eq!(parser.between("move ", " "), "10");
646/// assert_eq!(parser.between("from ", " "), "271");
647/// assert_eq!(parser.after("to "), "3");
648/// ```
649#[derive(Clone, Debug)]
650pub struct Parser<'a> {
651    inner: &'a str,
652}
653
654impl<'a> Parser<'a> {
655    /// Creates a new `Parser` from the given `&str`.
656    #[inline]
657    pub fn new(s: &'a str) -> Self {
658        Self { inner: s }
659    }
660
661    /// Skips past the next `n` bytes (ASCII characters) of the string.
662    ///
663    /// Future method calls on `self` will work on the remainder of the string.
664    ///
665    /// Both mutates `self` and returns a copy of `self` after the mutation.
666    ///
667    /// Panics if the string has less than `n` bytes left.
668    ///
669    /// # Examples
670    /// ```
671    /// use aoc::Parse;
672    ///
673    /// let s = "12345foo1234567bar";
674    /// let mut parser = s.as_parser().skip(5);
675    ///
676    /// assert_eq!(parser.take(3), "foo");
677    /// parser.skip(7);
678    /// assert_eq!(parser.rest(), "bar");
679    /// ```
680    #[inline]
681    #[track_caller]
682    pub fn skip(&mut self, n: usize) -> Self {
683        self.inner = &self.inner[n..];
684        self.clone()
685    }
686
687    /// Returns the next `n` bytes (ASCII characters) of the string.
688    ///
689    /// Future method calls on `self` will then work on the remainder of the string.
690    ///
691    /// Panics if the string has less than `n` bytes left.
692    ///
693    /// # Examples
694    /// ```
695    /// use aoc::Parse;
696    ///
697    /// let s = "12345foo1234567bar.";
698    /// let mut parser = s.as_parser().skip(5);
699    ///
700    /// assert_eq!(parser.take(3), "foo");
701    /// parser.skip(7);
702    /// assert_eq!(parser.take(3), "bar");
703    /// ```
704    #[track_caller]
705    pub fn take(&mut self, n: usize) -> &str {
706        let first = &self.inner[..n];
707        self.inner = &self.inner[n..];
708        first
709    }
710
711    /// Returns the remainder of the string, consuming `self`.
712    ///
713    /// # Examples
714    /// ```
715    /// use aoc::Parse;
716    ///
717    /// let s = "hello, world!";
718    /// let mut parser = s.as_parser();
719    ///
720    /// parser.skip(7);
721    /// assert_eq!(parser.rest(), "world!");
722    /// ```
723    #[inline]
724    pub fn rest(self) -> &'a str {
725        self.inner
726    }
727
728    /// Returns the slice of the string before the first occurrence of `suffix`.
729    ///
730    /// Future method calls on `self` will then work on the remainder of the string after `suffix`.
731    ///
732    /// Panics if `suffix` is not contained in the remainder of the string.
733    ///
734    /// # Examples
735    /// ```
736    /// use aoc::Parse;
737    ///
738    /// let s = "move 10 from 271 to 3";
739    /// let mut parser = s.as_parser().skip(5);
740    ///
741    /// assert_eq!(parser.before(" "), "10");
742    /// parser.skip(5);
743    /// assert_eq!(parser.before(" "), "271");
744    /// parser.skip(3);
745    /// assert_eq!(parser.rest(), "3");
746    /// ```
747    #[track_caller]
748    pub fn before(&mut self, suffix: &str) -> &'a str {
749        let (before, after) = self
750            .inner
751            .split_once(suffix)
752            .expect("`suffix` should be contained in the string");
753        self.inner = after;
754        before
755    }
756
757    /// Returns the slice of the string after the first occurrence of `prefix`, consuming `self`.
758    ///
759    /// Panics if `prefix` is not contained in the remainder of the string.
760    ///
761    /// # Examples
762    /// ```
763    /// use aoc::Parse;
764    ///
765    /// let s = "move 10 from 271 to 3";
766    /// let mut parser = s.as_parser();
767    ///
768    /// assert_eq!(parser.between(" ", " "), "10");
769    /// assert_eq!(parser.between(" ", " "), "271");
770    /// assert_eq!(parser.after(" "), "3");
771    /// ```
772    #[track_caller]
773    pub fn after(self, prefix: &str) -> &'a str {
774        let i = self
775            .inner
776            .find(prefix)
777            .expect("`prefix` should be contained in the string")
778            + prefix.len();
779        &self.inner[i..]
780    }
781
782    /// Returns the slice of the string after the first occurrence of `prefix`, and before the next occurrence of `suffix`.
783    ///
784    /// Future method calls on `self` will then work on the remainder of the string after `suffix`.
785    ///
786    /// # Examples
787    /// ```
788    /// use aoc::Parse;
789    ///
790    /// let s = "move 10 from 271 to 3";
791    /// let mut parser = s.as_parser();
792    ///
793    /// assert_eq!(parser.between("move ", " "), "10");
794    /// assert_eq!(parser.between("from ", " "), "271");
795    /// assert_eq!(parser.after("to "), "3");
796    /// ```
797    #[track_caller]
798    pub fn between(&mut self, prefix: &str, suffix: &str) -> &'a str {
799        *self = Self {
800            inner: self.clone().after(prefix),
801        };
802        self.before(suffix)
803    }
804}