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}