yap/
tokens.rs

1//! The point of this library. This module contains the core [`Tokens`] trait, which adds
2//! various convenience methods on top of an [`Iterator`] based interface aimed at making
3//! it easy to parse things.
4//!
5//! The [`IntoTokens`] trait is also provided, and can be implemented for types that can be
6//! converted into something implementing the [`Tokens`] trait (for example `&str` and `&[T]`).
7mod many;
8mod many_err;
9mod sep_by;
10mod sep_by_all;
11mod sep_by_all_err;
12mod sep_by_err;
13mod slice;
14mod take;
15mod take_while;
16
17use core::borrow::Borrow;
18use core::ops::Deref;
19use core::str::FromStr;
20
21// Re-export the structs handed back from token fns:
22pub use many::Many;
23pub use many_err::ManyErr;
24pub use sep_by::SepBy;
25pub use sep_by_all::SepByAll;
26pub use sep_by_all_err::SepByAllErr;
27pub use sep_by_err::SepByErr;
28pub use slice::Slice;
29pub use take::Take;
30pub use take_while::TakeWhile;
31
32use crate::types::{WithContext, WithContextMut};
33
34/// The tokens trait is an extension of the [`Iterator`] trait, and adds a bunch of useful methods
35/// for parsing tokens from the underlying iterable type.
36///
37/// Implementations don't need to directly implement [`Iterator`]; instead there exists
38/// [`Tokens::as_iter()`] and [`Tokens::into_iter()`] methods to return an iterator that is based
39/// on the methods implemented here and keeps iterator methods in a separate namespace.
40pub trait Tokens: Sized {
41    /// The item returned from [`Tokens::next()`].
42    type Item;
43
44    /// An object which can be used to reset the token stream
45    /// to some position.
46    type Location: TokenLocation + PartialEq + core::fmt::Debug + Clone;
47
48    /// Return the next token. This is also the basis of the [`Iterator`] implementation
49    /// that's returned when you call [`Tokens::as_iter()`]. By implementing it here, we can keep
50    /// all of the methods provided by [`Iterator`] in a separate "namespace" to avoid confusion
51    /// and potential name collisions.
52    ///
53    /// # Example
54    ///
55    /// ```rust
56    /// use yap::{ Tokens, IntoTokens };
57    ///
58    /// let mut s = "abc".into_tokens();
59    ///
60    /// assert_eq!(s.next(), Some('a'));
61    /// assert_eq!(s.next(), Some('b'));
62    /// assert_eq!(s.next(), Some('c'));
63    /// assert_eq!(s.next(), None);
64    /// ```
65    fn next(&mut self) -> Option<Self::Item>;
66
67    /// Return a "location" pointer. This can be passed to [`Tokens::set_location`]
68    /// to set the tokens location back to the state at the time it was handed out.
69    /// If the [`crate::TokenLocation`] trait is in scope, you can also call the
70    /// [`crate::TokenLocation::offset()`] method on it to obtain the current offset.
71    ///
72    /// # Example
73    ///
74    /// ```rust
75    /// use yap::{ Tokens, IntoTokens, TokenLocation };
76    ///
77    /// let mut s = "abcde".into_tokens();
78    ///
79    /// let location = s.location();
80    /// assert_eq!(s.next().unwrap(), 'a');
81    /// assert_eq!(s.location().offset(), 1);
82    /// assert_eq!(s.next().unwrap(), 'b');
83    /// assert_eq!(s.location().offset(), 2);
84    ///
85    /// s.set_location(location);
86    ///
87    /// assert_eq!(s.next().unwrap(), 'a');
88    /// assert_eq!(s.location().offset(), 1);
89    /// assert_eq!(s.next().unwrap(), 'b');
90    /// assert_eq!(s.location().offset(), 2);
91    /// ```
92    fn location(&self) -> Self::Location;
93
94    /// Set the tokens to the location provided. See [`Tokens::location`].
95    fn set_location(&mut self, location: Self::Location);
96
97    /// Return true if the current cursor location matches the location given, or false
98    /// otherwise.
99    ///
100    /// # Example
101    ///
102    /// ```
103    /// use yap::{ Tokens, IntoTokens };
104    ///
105    /// let mut s = "abc".into_tokens();
106    /// let location = s.location();
107    /// assert_eq!(s.is_at_location(&location), true);
108    /// s.next();
109    /// assert_eq!(s.is_at_location(&location), false);
110    /// s.set_location(location);
111    /// assert_eq!(s.is_at_location(&location), true);
112    /// ```
113    fn is_at_location(&self, location: &Self::Location) -> bool;
114
115    /// Return an iterator over our tokens. The [`Tokens`] trait already mirrors the [`Iterator`]
116    /// interface by providing [`Tokens::Item`] and [`Tokens::next()`], but we keep the [`Iterator`]
117    /// separate to avoid collisions, and because some iterator methods don't consume tokens as you
118    /// might expect, and so must be used with care when parsing input.
119    fn as_iter(&'_ mut self) -> TokensAsIter<'_, Self> {
120        TokensAsIter { tokens: self }
121    }
122
123    /// Like [`Tokens::as_iter()`], except it consumes `self`, which can be useful in some situations.
124    fn into_iter(self) -> TokensIntoIter<Self> {
125        TokensIntoIter { tokens: self }
126    }
127
128    /// Attempt to parse the remaining tokens into the first `Out` generic using [`str::parse()`].
129    /// The second generic type may be used to buffer tokens, and can be any type that implements
130    /// `FromIterator<Self::Item> + Deref<Target = str>`.
131    ///
132    /// If the parsing fails, then no tokens are consumed.
133    ///
134    /// As an optimisation, implementations may choose not to use the provided buffer type if they have a
135    /// suitable internal buffer of their own already. This is the case for [`crate::types::StrTokens`].
136    ///
137    /// This is mostly expected to be used in conjunction with [`Tokens::take`] and [`Tokens::take_while`],
138    /// which themselves return the matching [`Tokens`].
139    ///
140    /// # Example
141    ///
142    /// ```
143    /// use yap::{ Tokens, IntoTokens };
144    ///
145    /// let mut tokens = "123abc456".into_tokens();
146    ///
147    /// let n = tokens.take(3).parse::<u8, String>().unwrap();
148    /// assert_eq!(n, 123);
149    ///
150    /// let s = tokens.take_while(|t| t.is_alphabetic()).parse::<String, String>().unwrap();
151    /// assert_eq!(s, "abc".to_string());
152    ///
153    /// // This will fail to parse; the number is out of bounds. Failure will consume
154    /// // no tokens.
155    /// assert!(tokens.parse::<u8, String>().is_err());
156    ///
157    /// // This will work; the number can fit into a u16:
158    /// let n2 = tokens.parse::<u16, String>().unwrap();
159    /// assert_eq!(n2, 456);
160    /// ```
161    fn parse<Out, Buf>(&mut self) -> Result<Out, <Out as FromStr>::Err>
162    where
163        Out: FromStr,
164        Buf: FromIterator<Self::Item> + Deref<Target = str>,
165    {
166        self.optional_err(|toks| toks.collect::<Buf>().parse::<Out>())
167    }
168
169    /// This is called when `tokens.slice(..).parse()` is called, and exists so that `Tokens`
170    /// impls have the chance to override/optimise this behaviour.
171    ///
172    /// This should never alter the location of the underlying tokens.
173    #[doc(hidden)]
174    fn parse_slice<Out, Buf>(
175        &mut self,
176        from: Self::Location,
177        to: Self::Location,
178    ) -> Result<Out, <Out as FromStr>::Err>
179    where
180        Out: FromStr,
181        Buf: FromIterator<Self::Item> + Deref<Target = str>,
182    {
183        self.slice(from, to).collect::<Buf>().parse::<Out>()
184    }
185
186    /// This is called when `tokens.take_while(..).parse()` is called, and exists so that `Tokens`
187    /// impls have the chance to override/optimise this behaviour.
188    ///
189    /// This should consume tokens on success, and consume nothing on failure.
190    #[doc(hidden)]
191    fn parse_take_while<Out, Buf, F>(&mut self, take_while: F) -> Result<Out, <Out as FromStr>::Err>
192    where
193        Out: FromStr,
194        Buf: FromIterator<Self::Item> + Deref<Target = str>,
195        F: FnMut(&Self::Item) -> bool,
196    {
197        self.optional_err(|toks| toks.take_while(take_while).collect::<Buf>().parse::<Out>())
198    }
199
200    /// This is called when `tokens.take(..).parse()` is called, and exists so that `Tokens`
201    /// impls have the chance to override/optimise this behaviour.
202    ///
203    /// This should consume tokens on success, and consume nothing on failure.
204    #[doc(hidden)]
205    fn parse_take<Out, Buf>(&mut self, n: usize) -> Result<Out, <Out as FromStr>::Err>
206    where
207        Out: FromStr,
208        Buf: FromIterator<Self::Item> + Deref<Target = str>,
209    {
210        self.optional_err(|toks| toks.take(n).collect::<Buf>().parse::<Out>())
211    }
212
213    /// Attach some context to your tokens. The returned struct, [`WithContext`], also implements
214    /// [`Tokens`], and so has can be used in much the same way. Since this consumes your tokens, it's
215    /// better suited to permanent context that you'd like throughout the parsing.
216    ///
217    /// See [`Tokens::with_context_mut`] for a version that's easier to attach temporary context with.
218    ///
219    /// # Example
220    ///
221    /// ```
222    /// use yap::{ Tokens, IntoTokens, types::WithContext };
223    ///
224    /// fn skip_digits(toks: &mut WithContext<impl Tokens<Item=char>, usize>) {
225    ///     let n_skipped = toks.skip_while(|c| c.is_digit(10));
226    ///     *toks.context_mut() += n_skipped;
227    /// }
228    ///
229    /// let mut tokens = "123abc456".into_tokens().with_context(0usize);
230    ///
231    /// skip_digits(&mut tokens);
232    /// tokens.skip_while(|c| c.is_alphabetic());
233    /// skip_digits(&mut tokens);
234    ///
235    /// assert_eq!(*tokens.context(), 6);
236    /// ```
237    fn with_context<C>(self, context: C) -> WithContext<Self, C> {
238        WithContext::new(self, context)
239    }
240
241    /// Unlike [`Tokens::with_context`], which consumes the tokens, this borrows them mutably, allowing it to
242    /// be used when you only have a mutable reference to tokens (which is a common function signature to use),
243    /// and making it better suited to attaching temporary contexts.
244    ///
245    /// Be aware that if you attach context in a function called recursively, the type checker may shout at you
246    /// for constructing a type like `WithContextMut<WithContextMut<WithContextMut<..>>>`. In these cases, you
247    /// can "break the cycle" by removing the original `WithContextMut` by using
248    /// [`crate::types::WithContextMut::into_parts()`] before wrapping the tokens in a new context for the recursive
249    /// call.
250    ///
251    /// # Example
252    ///
253    /// ```
254    /// use yap::{ Tokens, IntoTokens };
255    ///
256    /// fn count_digit_comma_calls(toks: &mut impl Tokens<Item=char>) -> (u8, u8) {
257    ///     let mut counts = (0u8, 0u8);
258    ///     toks.with_context_mut(&mut counts).sep_by(
259    ///         |t| {
260    ///             t.context_mut().0 += 1;
261    ///             let n_skipped = t.skip_while(|c| c.is_digit(10));
262    ///             if n_skipped == 0 { None } else { Some(()) }
263    ///         },
264    ///         |t| {
265    ///             t.context_mut().1 += 1;
266    ///             t.token(',')
267    ///         }
268    ///     ).consume();
269    ///     counts
270    /// }
271    ///
272    /// let n: usize = 0;
273    /// let mut tokens = "123,4,56,1,34,1".into_tokens();
274    ///
275    /// let (digits, seps) = count_digit_comma_calls(&mut tokens);
276    ///
277    /// assert_eq!(tokens.remaining().len(), 0);
278    /// // digits parsed 6 times:
279    /// assert_eq!(digits, 6);
280    /// // Attempted to parse seps 6 times; failure on last ends it:
281    /// assert_eq!(seps, 6);
282    /// ```
283    fn with_context_mut<C>(&mut self, context: C) -> WithContextMut<&mut Self, C> {
284        WithContextMut::new(self, context)
285    }
286
287    /// Return a slice of tokens starting at the `to` location provided and ending just prior to
288    /// the `from` location provided (ie equivalent to the range `to..from`).
289    ///
290    /// The slice returned from implements [`Tokens`], so you can use the full range
291    /// of parsing functions on it.
292    ///
293    /// **Note:** the slice returned from this prevents the original tokens from being used until
294    /// it's dropped, and resets the original tokens to their current location on `Drop`. if you
295    /// [`core::mem::forget`] it, the original token location will equal whatever the slice location
296    /// was when it was forgotten.
297    ///
298    /// # Example
299    ///
300    /// ```rust
301    /// use yap::{ Tokens, IntoTokens };
302    ///
303    /// let mut s = "abcdefghijklmnop".into_tokens();
304    ///
305    /// (0..5).for_each(|_| { s.next(); });
306    /// let from = s.location();
307    /// (0..5).for_each(|_| { s.next(); });
308    /// let to = s.location();
309    ///
310    /// assert_eq!(s.next(), Some('k'));
311    /// assert_eq!(s.next(), Some('l'));
312    ///
313    /// // Iterating the from..to range given:
314    /// let vals: String = s.slice(from.clone(), to.clone()).collect();
315    /// assert_eq!(&*vals, "fghij");
316    ///
317    /// // After the above is dropped, we can continue
318    /// // from where we left off:
319    /// assert_eq!(s.next(), Some('m'));
320    /// assert_eq!(s.next(), Some('n'));
321    ///
322    /// // We can iterate this range again as we please:
323    /// let vals: String = s.slice(from, to).collect();
324    /// assert_eq!(&*vals, "fghij");
325    ///
326    /// // And the original remains unaffected..
327    /// assert_eq!(s.next(), Some('o'));
328    /// assert_eq!(s.next(), Some('p'));
329    /// ```
330    fn slice(&'_ mut self, from: Self::Location, to: Self::Location) -> Slice<'_, Self> {
331        Slice::new(self, self.location(), from, to)
332    }
333
334    /// Return the current offset into the tokens that we've parsed up to so far.
335    /// The exact meaning of this can vary by implementation; when parsing slices, it
336    /// is index of the slice item we've consumed up to, and when
337    /// parsing `&str`'s it is the number of bytes (not characters) consumed so far.
338    ///
339    /// # Example
340    ///
341    /// ```
342    /// use yap::{ Tokens, IntoTokens };
343    ///
344    /// let mut s = "abc".into_tokens();
345    /// assert_eq!(s.offset(), 0);
346    /// s.next();
347    /// assert_eq!(s.offset(), 1);
348    /// s.next();
349    /// assert_eq!(s.offset(), 2);
350    /// ```
351    fn offset(&self) -> usize {
352        self.location().offset()
353    }
354
355    /// Return the next item in the input without consuming it.
356    ///
357    /// Prefer this to using the `peekable` iterator method, which consumes
358    /// the tokens, and internally keeps hold of the peeked state itself.
359    ///
360    /// # Example
361    ///
362    /// ```
363    /// use yap::{ Tokens, IntoTokens };
364    ///
365    /// let mut s = "abc".into_tokens();
366    /// assert_eq!(s.peek(), Some('a'));
367    /// assert_eq!(s.peek(), Some('a'));
368    /// ```
369    fn peek(&mut self) -> Option<Self::Item> {
370        let location = self.location();
371        let item = self.next();
372        self.set_location(location);
373        item
374    }
375
376    /// Expect a specific token to be next. If the token is not found, the iterator is not
377    /// advanced.
378    ///
379    /// # Example
380    ///
381    /// ```
382    /// use yap::{ Tokens, IntoTokens };
383    ///
384    /// let mut s = "abc".into_tokens();
385    /// assert_eq!(s.token(&'a'), true);
386    /// assert_eq!(s.token(&'b'), true);
387    /// assert_eq!(s.token('z'), false);
388    /// assert_eq!(s.token('y'), false);
389    /// assert_eq!(s.token('c'), true);
390    /// ```
391    fn token<I>(&mut self, t: I) -> bool
392    where
393        Self::Item: PartialEq,
394        I: Borrow<Self::Item>,
395    {
396        let location = self.location();
397        match self.next() {
398            Some(item) if &item == t.borrow() => true,
399            _ => {
400                self.set_location(location);
401                false
402            }
403        }
404    }
405
406    /// Expect a specific set of tokens to be next. If the tokens are not found, the iterator is not
407    /// advanced. Anything that implements `IntoIterator` with an `Item` type that can be borrowed to
408    /// produce `&Item` can be provided as an input to this.
409    ///
410    /// # Example
411    ///
412    /// ```
413    /// use yap::{ Tokens, IntoTokens };
414    ///
415    /// let mut s = "abcdef".into_tokens();
416    ///
417    /// assert_eq!(s.tokens("abc".chars()), true);
418    /// assert_eq!(s.remaining(), "def");
419    ///
420    /// assert_eq!(s.tokens("de".chars()), true);
421    /// assert_eq!(s.remaining(), "f");
422    /// ```
423    fn tokens<It>(&mut self, ts: It) -> bool
424    where
425        Self::Item: PartialEq,
426        It: IntoIterator,
427        It::Item: Borrow<Self::Item>,
428    {
429        let location = self.location();
430
431        // We don't `.zip()` here because we need to spot and handle the
432        // case where we run out of self tokens before `ts` runs out, and reset
433        // /return false in that situation.
434        let ts_iter = ts.into_iter();
435        for expected in ts_iter {
436            match self.next() {
437                Some(actual) => {
438                    // We have a token; does it equal the expected one?
439                    if &actual != expected.borrow() {
440                        self.set_location(location);
441                        return false;
442                    }
443                }
444                None => {
445                    // We ran out of tokens in self, so no match.
446                    self.set_location(location);
447                    return false;
448                }
449            }
450        }
451        true
452    }
453
454    /// Return the first token that matches the tokens provided, or None if none of them
455    /// match.
456    ///
457    /// # Example
458    ///
459    /// ```
460    /// use yap::{ Tokens, IntoTokens };
461    ///
462    /// let mut s = "abcdef".into_tokens();
463    ///
464    /// assert_eq!(s.one_of_tokens("abc".chars()), Some('a'));
465    /// assert_eq!(s.one_of_tokens("abc".chars()), Some('b'));
466    /// assert_eq!(s.one_of_tokens("abc".chars()), Some('c'));
467    /// assert_eq!(s.one_of_tokens("abc".chars()), None);
468    /// assert_eq!(s.remaining(), "def");
469    /// ```
470    fn one_of_tokens<It>(&mut self, ts: It) -> Option<Self::Item>
471    where
472        Self::Item: PartialEq,
473        It: IntoIterator,
474        It::Item: Borrow<Self::Item>,
475    {
476        for expected in ts.into_iter() {
477            let location = self.location();
478            match self.next() {
479                Some(token) if &token == expected.borrow() => return Some(token),
480                _ => {
481                    self.set_location(location);
482                }
483            }
484        }
485        None
486    }
487
488    /// Return a [`Tokens`] impl that will take the next `n` tokens from the input (ending early
489    /// if the input runs early).
490    ///
491    /// # Example
492    ///
493    /// ```
494    /// use yap::{ Tokens, IntoTokens };
495    ///
496    /// let mut s = "12345abc".into_tokens();
497    /// let digits: String = s.take(3).collect();
498    /// assert_eq!(&*digits, "123");
499    /// assert_eq!(s.remaining(), "45abc");
500    /// ```
501    fn take(&'_ mut self, n: usize) -> Take<'_, Self> {
502        Take::new(self, n)
503    }
504
505    /// Return a [`Tokens`] impl that will consume tokens until the provided function returns false.
506    ///
507    /// # Example
508    ///
509    /// ```
510    /// use yap::{ Tokens, IntoTokens };
511    ///
512    /// let mut s = "12345abc".into_tokens();
513    /// let digits: String = s.take_while(|c| c.is_numeric()).collect();
514    /// assert_eq!(&*digits, "12345");
515    /// assert_eq!(s.remaining(), "abc");
516    /// ```
517    ///
518    /// This exists primarily because [`Iterator::take_while()`] will consume the first token that
519    /// does not match the predicate, which is often not what we'd want. The above example using
520    /// [`Iterator::take_while()`] would look like:
521    ///
522    /// ```rust
523    /// use yap::{ Tokens, IntoTokens };
524    ///
525    /// let mut s = "12345abc".into_tokens();
526    /// let digits: String = s.as_iter().take_while(|c| c.is_numeric()).collect();
527    /// assert_eq!(&*digits, "12345");
528    ///
529    /// // Note that `Iterator::take_while` consumed the "a" in order to test it,
530    /// // whereas `Tokens::take_while` did not:
531    /// assert_eq!(s.remaining(), "bc");
532    /// ```
533    fn take_while<F>(&'_ mut self, f: F) -> TakeWhile<'_, Self, F>
534    where
535        F: FnMut(&Self::Item) -> bool,
536    {
537        TakeWhile::new(self, f)
538    }
539
540    /// Iterate over the tokens until the provided function returns false on one. Only consume the tokens
541    /// that the function returned true for, returning the number of tokens that were consumed/skipped.
542    /// Equivalent to `toks.take_while(f).count()`.
543    ///
544    /// # Example
545    ///
546    /// ```
547    /// use yap::{ Tokens, IntoTokens };
548    ///
549    /// let mut s = "12345abc".into_tokens();
550    /// let n_skipped = s.skip_while(|c| c.is_numeric());
551    ///
552    /// assert_eq!(n_skipped, 5);
553    /// assert_eq!(s.remaining(), "abc");
554    /// ```
555    fn skip_while<F>(&mut self, f: F) -> usize
556    where
557        F: FnMut(&Self::Item) -> bool,
558    {
559        self.take_while(f).as_iter().count()
560    }
561
562    /// Returns a [`Tokens`] impl that runs the provided parser again and again, returning
563    /// an output from it each time until it returns [`None`].
564    ///
565    /// # Example
566    ///
567    /// ```rust
568    /// use yap::{ Tokens, IntoTokens };
569    ///
570    /// fn parse_digit_pair(tokens: &mut impl Tokens<Item=char>) -> Option<u32> {
571    ///     let d1 = tokens.next()?;
572    ///     let d2 = tokens.next()?;
573    ///     // Return the result of adding the 2 digits we saw:
574    ///     Some(d1.to_digit(10)? + d2.to_digit(10)?)
575    /// }
576    ///
577    /// let mut s = "12345abcde".into_tokens();
578    /// let digits: Vec<u32> = s.many(|t| parse_digit_pair(t)).collect();
579    ///
580    /// assert_eq!(digits, vec![3, 7]);
581    /// assert_eq!(s.remaining(), "5abcde");
582    /// ```
583    fn many<F, Output>(&mut self, parser: F) -> Many<Self, F>
584    where
585        F: FnMut(&mut Self) -> Option<Output>,
586    {
587        Many::new(self, parser)
588    }
589
590    /// Returns a [`Tokens`] impl that runs the provided parser again and again, returning
591    /// an output from it each time until it returns [`None`]. If the parser returns an error,
592    /// no tokens will be consumed and the error will be returned as the final iteration.
593    ///
594    /// # Example
595    ///
596    /// ```rust
597    /// use yap::{ Tokens, IntoTokens };
598    ///
599    /// #[derive(Debug, PartialEq)]
600    /// enum Err { NotEnoughTokens, NotADigit(char) }
601    /// fn parse_digit_pair(tokens: &mut impl Tokens<Item=char>) -> Result<u32, Err> {
602    ///     let n1 = tokens.next()
603    ///         .ok_or(Err::NotEnoughTokens)
604    ///         .and_then(|c| c.to_digit(10).ok_or(Err::NotADigit(c)))?;
605    ///     let n2 = tokens.next()
606    ///         .ok_or(Err::NotEnoughTokens)
607    ///         .and_then(|c| c.to_digit(10).ok_or(Err::NotADigit(c)))?;
608    ///     Ok(n1 + n2)
609    /// }
610    ///
611    /// let mut s = "12345abcde".into_tokens();
612    /// let mut digits_iter = s.many_err(|t| parse_digit_pair(t));
613    ///
614    /// assert_eq!(digits_iter.next(), Some(Ok(3)));
615    /// assert_eq!(digits_iter.next(), Some(Ok(7)));
616    /// assert_eq!(digits_iter.next(), Some(Err(Err::NotADigit('a'))));
617    /// assert_eq!(digits_iter.next(), None);
618    /// assert_eq!(s.remaining(), "5abcde");
619    /// ```
620    fn many_err<F, Output, E>(&'_ mut self, parser: F) -> ManyErr<'_, Self, F>
621    where
622        F: FnMut(&mut Self) -> Result<Output, E>,
623    {
624        ManyErr::new(self, parser)
625    }
626
627    /// Ignore 0 or more instances of some parser.
628    ///
629    /// # Example
630    ///
631    /// ```rust
632    /// use yap::{ Tokens, IntoTokens };
633    ///
634    /// struct ABC;
635    /// fn parse_abc(tokens: &mut impl Tokens<Item=char>) -> Option<ABC> {
636    ///     let a = tokens.next()?;
637    ///     let b = tokens.next()?;
638    ///     let c = tokens.next()?;
639    ///     if a == 'a' && b == 'b' && c == 'c' {
640    ///         Some(ABC)
641    ///     } else {
642    ///         None
643    ///     }
644    /// }
645    ///
646    /// let mut s = "abcabcababab".into_tokens();
647    /// s.skip_many(|t| parse_abc(t).is_some());
648    ///
649    /// assert_eq!(s.remaining(), "ababab");
650    /// ```
651    fn skip_many<F>(&mut self, mut parser: F) -> usize
652    where
653        F: FnMut(&mut Self) -> bool,
654    {
655        self.many(|t| parser(t).then_some(())).as_iter().count()
656    }
657
658    /// Ignore 1 or more instances of some parser. If the provided parser
659    /// fails immediately, return the error that it produced.
660    ///
661    /// # Example
662    ///
663    /// ```rust
664    /// use yap::{ Tokens, IntoTokens };
665    ///
666    /// struct ABC;
667    /// fn parse_abc(tokens: &mut impl Tokens<Item=char>) -> Option<ABC> {
668    ///     let a = tokens.next()?;
669    ///     let b = tokens.next()?;
670    ///     let c = tokens.next()?;
671    ///     if a == 'a' && b == 'b' && c == 'c' {
672    ///         Some(ABC)
673    ///     } else {
674    ///         None
675    ///     }
676    /// }
677    ///
678    /// let mut s = "abcabcabcxyz".into_tokens();
679    /// let skipped = s.skip_many1(|t| parse_abc(t).ok_or("aaah"));
680    ///
681    /// assert_eq!(skipped, Ok(3));
682    /// assert_eq!(s.remaining(), "xyz");
683    ///
684    /// let mut s = "ababababcabc".into_tokens();
685    /// let skipped = s.skip_many1(|t| parse_abc(t).ok_or("aaah"));
686    ///
687    /// assert_eq!(skipped, Err("aaah"));
688    /// assert_eq!(s.remaining(), "ababababcabc");
689    /// ```
690    fn skip_many1<F, E, Ignored>(&mut self, parser: F) -> Result<usize, E>
691    where
692        F: FnMut(&mut Self) -> Result<Ignored, E>,
693    {
694        let mut toks = self.many_err(parser);
695        // Return error if immediate fail:
696        if let Some(Err(e)) = toks.next() {
697            return Err(e);
698        }
699        // Else just consume whatever we can and count it all up.
700        // Note: the last iteration of `many_err` will return an Error
701        // and not a value, so where we'd otherwise `+1` this count to
702        // account for the `iter.next()` above, we don't have to.
703        let n_skipped = toks.as_iter().count();
704        Ok(n_skipped)
705    }
706
707    /// Return a [`Tokens`] impl that parses anything matching the first `parser` function,
708    /// and expects to parse something matching the second `separator` function between each
709    /// of these.
710    ///
711    /// # Example
712    ///
713    /// ```
714    /// use yap::{ Tokens, IntoTokens };
715    ///
716    /// fn parse_digit(tokens: &mut impl Tokens<Item=char>) -> Option<u32> {
717    ///     let c = tokens.next()?;
718    ///     c.to_digit(10)
719    /// }
720    ///
721    /// let mut s = "1,2,3,4,abc".into_tokens();
722    /// let digits: Vec<u32> = s.sep_by(|t| parse_digit(t), |t| t.token(',')).collect();
723    /// assert_eq!(digits, vec![1,2,3,4]);
724    /// assert_eq!(s.remaining(), ",abc");
725    /// ```
726    fn sep_by<F, S, Output>(&'_ mut self, parser: F, separator: S) -> SepBy<'_, Self, F, S>
727    where
728        F: FnMut(&mut Self) -> Option<Output>,
729        S: FnMut(&mut Self) -> bool,
730    {
731        SepBy::new(self, parser, separator)
732    }
733
734    /// Return a [`Tokens`] impl that parses anything matching the `parser` function, and expects
735    /// to parse something matching the `separator` function between each one. Unlike [`Tokens::sep_by`],
736    /// this accepts parsers that return `Result`s, and returns the result on each iteration. Once
737    /// an error is hit, `None` is returned thereafter.
738    ///
739    /// # Example
740    ///
741    /// ```
742    /// use yap::{ Tokens, IntoTokens };
743    ///
744    /// #[derive(Debug, PartialEq)]
745    /// enum Err { NoMoreTokens, NotADigit(char) }
746    ///
747    /// fn parse_digit(tokens: &mut impl Tokens<Item=char>) -> Result<u32, Err> {
748    ///     let c = tokens.next().ok_or(Err::NoMoreTokens)?;
749    ///     c.to_digit(10).ok_or(Err::NotADigit(c))
750    /// }
751    ///
752    /// let mut s = "1,2,a,1,2,3".into_tokens();
753    /// let mut digits_iter = s.sep_by_err(|t| parse_digit(t), |t| t.token(','));
754    /// assert_eq!(digits_iter.next(), Some(Ok(1)));
755    /// assert_eq!(digits_iter.next(), Some(Ok(2)));
756    /// assert_eq!(digits_iter.next(), Some(Err(Err::NotADigit('a'))));
757    /// assert_eq!(digits_iter.next(), None);
758    /// assert_eq!(s.remaining(), ",a,1,2,3");
759    /// ```
760    fn sep_by_err<F, S, E, Output>(
761        &'_ mut self,
762        parser: F,
763        separator: S,
764    ) -> SepByErr<'_, Self, F, S>
765    where
766        F: FnMut(&mut Self) -> Result<Output, E>,
767        S: FnMut(&mut Self) -> bool,
768    {
769        SepByErr::new(self, parser, separator)
770    }
771
772    /// Returns a [`Tokens`] impl that parses anything matching the `parser` function,
773    /// and expects to parse something matching the `separator` function between each one.
774    /// The [`Tokens`] impl hands back the output from both the `parser` and `separator`
775    /// function, which means that they are both expected to return the same type.
776    ///
777    /// # Example
778    ///
779    /// ```
780    /// use yap::{ Tokens, IntoTokens };
781    ///
782    /// #[derive(PartialEq,Debug)]
783    /// enum Op { Plus, Minus, Divide }
784    /// #[derive(PartialEq,Debug)]
785    /// enum OpOrDigit { Op(Op), Digit(u32) }
786    ///
787    /// fn parse_op(tokens: &mut impl Tokens<Item=char>) -> Option<Op> {
788    ///     match tokens.next()? {
789    ///         '-' => Some(Op::Minus),
790    ///         '+' => Some(Op::Plus),
791    ///         '/' => Some(Op::Divide),
792    ///         _ => None
793    ///     }
794    /// }
795    ///
796    /// fn parse_digit(tokens: &mut impl Tokens<Item=char>) -> Option<u32> {
797    ///     let c = tokens.next()?;
798    ///     c.to_digit(10)
799    /// }
800    ///
801    /// let mut s = "1+2/3-4+abc".into_tokens();
802    /// let output: Vec<_> = s.sep_by_all(
803    ///     |t| parse_digit(t).map(OpOrDigit::Digit),
804    ///     |t| parse_op(t).map(OpOrDigit::Op)
805    /// ).collect();
806    ///
807    /// assert_eq!(output, vec![
808    ///     OpOrDigit::Digit(1),
809    ///     OpOrDigit::Op(Op::Plus),
810    ///     OpOrDigit::Digit(2),
811    ///     OpOrDigit::Op(Op::Divide),
812    ///     OpOrDigit::Digit(3),
813    ///     OpOrDigit::Op(Op::Minus),
814    ///     OpOrDigit::Digit(4),
815    /// ]);
816    /// assert_eq!(s.remaining(), "+abc");
817    /// ```
818    fn sep_by_all<F, S, Output>(
819        &'_ mut self,
820        parser: F,
821        separator: S,
822    ) -> SepByAll<'_, Self, F, S, Output>
823    where
824        F: FnMut(&mut Self) -> Option<Output>,
825        S: FnMut(&mut Self) -> Option<Output>,
826    {
827        SepByAll::new(self, parser, separator)
828    }
829
830    /// Similar to [`Tokens::sep_by_all`], except that the [`Tokens`] impl returned also
831    /// hands back the first error encountered when attempting to run our `parser`.
832    ///
833    /// # Example
834    ///
835    /// ```
836    /// use yap::{ Tokens, IntoTokens };
837    ///
838    /// #[derive(PartialEq,Debug)]
839    /// enum Op { Plus, Minus, Divide }
840    /// #[derive(PartialEq,Debug)]
841    /// enum OpOrDigit { Op(Op), Digit(u32) }
842    /// #[derive(Debug, PartialEq)]
843    /// enum Err { NoMoreTokens, NotADigit(char) }
844    ///
845    /// fn parse_op(tokens: &mut impl Tokens<Item=char>) -> Option<Op> {
846    ///     match tokens.next()? {
847    ///         '-' => Some(Op::Minus),
848    ///         '+' => Some(Op::Plus),
849    ///         '/' => Some(Op::Divide),
850    ///         _ => None
851    ///     }
852    /// }
853    ///
854    /// fn parse_digit(tokens: &mut impl Tokens<Item=char>) -> Result<u32, Err> {
855    ///     let c = tokens.next().ok_or(Err::NoMoreTokens)?;
856    ///     c.to_digit(10).ok_or(Err::NotADigit(c))
857    /// }
858    ///
859    /// let mut s = "1+2/3-4+abc".into_tokens();
860    /// let output: Vec<_> = s.sep_by_all_err(
861    ///     |t| parse_digit(t).map(OpOrDigit::Digit),
862    ///     |t| parse_op(t).map(OpOrDigit::Op)
863    /// ).collect();
864    ///
865    /// assert_eq!(output, vec![
866    ///     Ok(OpOrDigit::Digit(1)),
867    ///     Ok(OpOrDigit::Op(Op::Plus)),
868    ///     Ok(OpOrDigit::Digit(2)),
869    ///     Ok(OpOrDigit::Op(Op::Divide)),
870    ///     Ok(OpOrDigit::Digit(3)),
871    ///     Ok(OpOrDigit::Op(Op::Minus)),
872    ///     Ok(OpOrDigit::Digit(4)),
873    ///     Err(Err::NotADigit('a'))
874    /// ]);
875    /// assert_eq!(s.remaining(), "+abc");
876    /// ```
877    fn sep_by_all_err<F, S, Output, E>(
878        &'_ mut self,
879        parser: F,
880        separator: S,
881    ) -> SepByAllErr<'_, Self, F, S, Output>
882    where
883        F: FnMut(&mut Self) -> Result<Output, E>,
884        S: FnMut(&mut Self) -> Option<Output>,
885    {
886        SepByAllErr::new(self, parser, separator)
887    }
888
889    /// Parse some tokens that are optionally surrounded by the result of a `surrounding` parser.
890    ///
891    /// # Example
892    ///
893    /// ```
894    /// use yap::{ Tokens, IntoTokens };
895    ///
896    /// let mut s = "   hello    ".into_tokens();
897    ///
898    /// let hello: String = s.surrounded_by(
899    ///     |t| t.take_while(|c| c.is_ascii_alphabetic()).collect(),
900    ///     |t| { t.skip_while(|c| c.is_ascii_whitespace()); }
901    /// );
902    ///
903    /// assert_eq!(&*hello, "hello");
904    /// assert_eq!(s.remaining(), "");
905    /// ```
906    fn surrounded_by<F, S, Output>(&mut self, parser: F, mut surrounding: S) -> Output
907    where
908        F: FnOnce(&mut Self) -> Output,
909        S: FnMut(&mut Self),
910    {
911        surrounding(self);
912        let res = parser(self);
913        surrounding(self);
914        res
915    }
916
917    /// Attempt to parse some output from the tokens. Returning `None`
918    /// or `false` signifies that no match was found, and no tokens will
919    /// be consumed. Otherwise, we'll return the match and consume the tokens.
920    ///
921    /// # Example
922    ///
923    /// ```
924    /// use yap::{ Tokens, IntoTokens };
925    ///
926    /// let mut s = "foobar".into_tokens();
927    ///
928    /// let res = s.optional(|s| {
929    ///     let a = s.next();
930    ///     let b = s.next();
931    ///     if a == b {
932    ///         Some("yay")
933    ///     } else {
934    ///         None
935    ///     }
936    /// });
937    ///
938    /// // nothing consumed since None returned from fn
939    /// assert_eq!(s.remaining(), "foobar");
940    /// assert_eq!(res, None);
941    ///
942    /// let res = s.optional(|s| {
943    ///     let a = s.next()?;
944    ///     let b = s.next()?;
945    ///     Some((a, b))
946    /// });
947    ///
948    /// // 2 chars consumed since Some returned from fn
949    /// assert_eq!(s.remaining(), "obar");
950    /// assert_eq!(res, Some(('f', 'o')));
951    /// ```
952    fn optional<F, Output>(&mut self, f: F) -> Output
953    where
954        F: FnOnce(&mut Self) -> Output,
955        Output: crate::one_of::IsMatch,
956    {
957        let location = self.location();
958        if let Some(output) = f(self).into_match() {
959            output
960        } else {
961            self.set_location(location);
962            crate::one_of::IsMatch::match_failure()
963        }
964    }
965
966    /// Attempt to parse some output from the tokens, returning a `Result`.
967    /// If the `Result` returned is `Err`, no tokens will be consumed.
968    ///
969    /// # Example
970    ///
971    /// ```
972    /// use yap::{ Tokens, IntoTokens };
973    ///
974    /// let mut s = "foobar".into_tokens();
975    ///
976    /// let res = s.optional_err(|s| {
977    ///     let a = s.next();
978    ///     let b = s.next();
979    ///     if a == b {
980    ///         Ok("yay")
981    ///     } else {
982    ///         Err("a and b don't match!")
983    ///     }
984    /// });
985    ///
986    /// // nothing consumed since Err returned from fn
987    /// assert_eq!(s.remaining(), "foobar");
988    /// assert!(res.is_err());
989    ///
990    /// let res = s.optional_err(|s| {
991    ///     let a = s.next();
992    ///     let b = s.next();
993    ///     if a != b {
994    ///         Ok((a, b))
995    ///     } else {
996    ///         Err("a and b match!")
997    ///     }
998    /// });
999    ///
1000    /// // 2 chars consumed since Ok returned from fn
1001    /// assert_eq!(s.remaining(), "obar");
1002    /// assert_eq!(res, Ok((Some('f'), Some('o'))));
1003    /// ```
1004    fn optional_err<F, Output, Error>(&mut self, f: F) -> Result<Output, Error>
1005    where
1006        F: FnOnce(&mut Self) -> Result<Output, Error>,
1007    {
1008        let location = self.location();
1009        match f(self) {
1010            Ok(output) => Ok(output),
1011            Err(err) => {
1012                self.set_location(location);
1013                Err(err)
1014            }
1015        }
1016    }
1017
1018    /// Checks next input is [`None`] and, if true, consumes the `None`.
1019    ///
1020    /// # Example
1021    ///
1022    /// ```
1023    /// use yap::Tokens;
1024    /// use yap::types::IterTokens;
1025    /// use core::iter;
1026    ///
1027    /// // This will always return None; eof will consume it.
1028    /// let mut toks = IterTokens::new(iter::empty::<char>());
1029    ///
1030    /// assert_eq!(toks.eof(), true);
1031    /// assert_eq!(toks.offset(), 1);
1032    ///
1033    /// assert_eq!(toks.eof(), true);
1034    /// assert_eq!(toks.offset(), 2);
1035    ///
1036    /// // This will return a char; eof won't consume anything.
1037    /// let mut toks = IterTokens::new(iter::once('a'));
1038    ///
1039    /// assert_eq!(toks.eof(), false);
1040    /// assert_eq!(toks.offset(), 0);
1041    ///
1042    /// assert_eq!(toks.eof(), false);
1043    /// assert_eq!(toks.offset(), 0);
1044    /// ```
1045    fn eof(&mut self) -> bool {
1046        self.optional(|t| t.next().is_none().then_some(()))
1047            .is_some()
1048    }
1049
1050    /// Consume all remaining tokens. This is expected to be used in conjunction
1051    /// with combinators like[`Tokens::take`] and [`Tokens::take_while`]. This is
1052    /// just a shorthand for `toks.as_iter().for_each(drop)`.
1053    ///
1054    /// # Example
1055    ///
1056    /// ```
1057    /// use yap::{Tokens, IntoTokens};
1058    ///
1059    /// let mut toks = "abc123def".into_tokens();
1060    ///
1061    /// // Take won't do anything unless it's consumed:
1062    /// toks.take(3);
1063    /// assert_eq!(toks.remaining(), "abc123def");
1064    ///
1065    /// // This is the same as `toks.take(3).as_iter().for_each(drop);`
1066    /// toks.take(3).consume();
1067    /// assert_eq!(toks.remaining(), "123def");
1068    ///
1069    /// toks.take_while(|t| t.is_numeric()).consume();
1070    /// assert_eq!(toks.remaining(), "def");
1071    /// ```
1072    fn consume(&mut self) {
1073        self.as_iter().for_each(drop)
1074    }
1075
1076    /// Collect up all of the tokens into something that implements
1077    /// [`FromIterator`]. If you'd like to call `str::parse` on the
1078    /// subsequent collection, then prefer [`Tokens::parse`], which can
1079    /// be more optimal in some cases.
1080    ///
1081    /// This is just a shorthand for calling `toks.as_iter().collect()`.
1082    fn collect<B: FromIterator<Self::Item>>(&mut self) -> B {
1083        self.as_iter().collect()
1084    }
1085}
1086
1087/// Calling [`Tokens::location()`] returns an object that implements this trait.
1088pub trait TokenLocation {
1089    /// Return the current offset into the tokens at the point at which this object
1090    /// was created. [`Tokens::offset()`] is simply a shorthand for calling this method
1091    /// at the current location.
1092    ///
1093    /// # Example
1094    ///
1095    /// ```
1096    /// use yap::{ Tokens, IntoTokens, TokenLocation };
1097    ///
1098    /// let mut s = "abc".into_tokens();
1099    /// assert_eq!(s.location().offset(), 0);
1100    /// s.next();
1101    /// assert_eq!(s.location().offset(), 1);
1102    /// s.next();
1103    /// assert_eq!(s.location().offset(), 2);
1104    /// ```
1105    fn offset(&self) -> usize;
1106}
1107
1108/// A trait that is implemented by anything which can be converted into an
1109/// object implementing the [`Tokens`] trait.
1110pub trait IntoTokens<Item> {
1111    /// The type that will be used to implement the [`Tokens`] interface.
1112    type Tokens: Tokens<Item = Item>;
1113    /// Convert self into a type which implements the [`Tokens`] interface.
1114    fn into_tokens(self) -> Self::Tokens;
1115}
1116
1117/// This is returned from [`Tokens::as_iter()`], and exposes the standard iterator
1118/// interface and methods on our tokens.
1119pub struct TokensAsIter<'a, T> {
1120    tokens: &'a mut T,
1121}
1122impl<'a, T: Tokens> Iterator for TokensAsIter<'a, T> {
1123    type Item = T::Item;
1124    fn next(&mut self) -> Option<Self::Item> {
1125        self.tokens.next()
1126    }
1127}
1128
1129/// This is returned from [`Tokens::into_iter()`], and exposes the standard iterator
1130/// interface and methods on our tokens.
1131pub struct TokensIntoIter<T> {
1132    tokens: T,
1133}
1134impl<T: Tokens> Iterator for TokensIntoIter<T> {
1135    type Item = T::Item;
1136    fn next(&mut self) -> Option<Self::Item> {
1137        self.tokens.next()
1138    }
1139}
1140
1141#[cfg(all(test, feature = "std"))]
1142mod test {
1143
1144    use crate::types::IterTokens;
1145
1146    use super::*;
1147
1148    #[derive(Debug, PartialEq)]
1149    struct AB;
1150
1151    // A simple parser that looks for "ab" in an input token stream.
1152    // Notably, it doesn't try to rewind on failure. We expect the `many`
1153    // combinators to take care of that sort of thing for us as needed.
1154    fn parse_ab(t: &mut impl Tokens<Item = char>) -> Option<AB> {
1155        // match any sequence "ab".
1156        let a = t.next()?;
1157        let b = t.next()?;
1158        if a == 'a' && b == 'b' {
1159            Some(AB)
1160        } else {
1161            None
1162        }
1163    }
1164
1165    // Similar to the above, except it reports a more specific reason for
1166    // failure.
1167    fn parse_ab_err(t: &mut impl Tokens<Item = char>) -> Result<AB, ABErr> {
1168        // match any sequence "ab".
1169        let a = t.next().ok_or(ABErr::NotEnoughTokens)?;
1170        let b = t.next().ok_or(ABErr::NotEnoughTokens)?;
1171
1172        if a != 'a' {
1173            Err(ABErr::IsNotA)
1174        } else if b != 'b' {
1175            Err(ABErr::IsNotB)
1176        } else {
1177            Ok(AB)
1178        }
1179    }
1180
1181    #[derive(Debug, PartialEq)]
1182    enum ABErr {
1183        NotEnoughTokens,
1184        IsNotA,
1185        IsNotB,
1186    }
1187
1188    #[test]
1189    fn test_tokens_fails_if_eof() {
1190        let mut t = "hi".into_tokens();
1191        assert!(!t.tokens("hip".chars()));
1192    }
1193
1194    #[test]
1195    #[allow(clippy::needless_collect)]
1196    fn test_many() {
1197        // No input:
1198        let mut t = "".into_tokens();
1199        let abs: Vec<_> = t.many(parse_ab).collect();
1200        let rest: Vec<char> = t.collect();
1201
1202        assert_eq!(abs.len(), 0);
1203        assert_eq!(rest, vec![]);
1204
1205        // Invalid input after half is consumed:
1206        let mut t = "acabab".into_tokens();
1207        let abs: Vec<_> = t.many(parse_ab).collect();
1208        let rest: Vec<char> = t.collect();
1209
1210        assert_eq!(abs.len(), 0);
1211        assert_eq!(rest, vec!['a', 'c', 'a', 'b', 'a', 'b']);
1212
1213        // 3 valid and then 1 half-invalid:
1214        let mut t = "abababaa".into_tokens();
1215        let abs: Vec<_> = t.many(parse_ab).collect();
1216        let rest: Vec<char> = t.collect();
1217
1218        assert_eq!(abs.len(), 3);
1219        assert_eq!(rest, vec!['a', 'a']);
1220
1221        // End of tokens before can parse the fourth:
1222        let mut t = "abababa".into_tokens();
1223        let abs: Vec<_> = t.many(parse_ab).collect();
1224        let rest: Vec<char> = t.collect();
1225
1226        assert_eq!(abs.len(), 3);
1227        assert_eq!(rest, vec!['a']);
1228    }
1229
1230    #[test]
1231    #[allow(clippy::needless_collect)]
1232    fn test_many_err() {
1233        // No input:
1234        let mut t = "".into_tokens();
1235        let abs: Vec<_> = t.many_err(parse_ab_err).collect();
1236        let rest: Vec<char> = t.collect();
1237
1238        assert_eq!(abs, vec![Err(ABErr::NotEnoughTokens)]);
1239        assert_eq!(rest, vec![]);
1240
1241        // Invalid input immediately:
1242        let mut t = "ccabab".into_tokens();
1243        let abs: Vec<_> = t.many_err(parse_ab_err).collect();
1244        let rest: Vec<char> = t.collect();
1245
1246        assert_eq!(abs, vec![Err(ABErr::IsNotA)]);
1247        assert_eq!(rest, vec!['c', 'c', 'a', 'b', 'a', 'b']);
1248
1249        // Invalid input after half is consumed:
1250        let mut t = "acabab".into_tokens();
1251        let abs: Vec<_> = t.many_err(parse_ab_err).collect();
1252        let rest: Vec<char> = t.collect();
1253
1254        assert_eq!(abs, vec![Err(ABErr::IsNotB)]);
1255        assert_eq!(rest, vec!['a', 'c', 'a', 'b', 'a', 'b']);
1256
1257        // 3 valid and then 1 half-invalid:
1258        let mut t = "abababaa".into_tokens();
1259        let abs: Vec<_> = t.many_err(parse_ab_err).collect();
1260        let rest: Vec<char> = t.collect();
1261
1262        assert_eq!(abs, vec![Ok(AB), Ok(AB), Ok(AB), Err(ABErr::IsNotB)]);
1263        assert_eq!(rest, vec!['a', 'a']);
1264
1265        // End of tokens before can parse the fourth:
1266        let mut t = "abababa".into_tokens();
1267        let abs: Vec<_> = t.many_err(parse_ab_err).collect();
1268        let rest: Vec<char> = t.collect();
1269
1270        assert_eq!(
1271            abs,
1272            vec![Ok(AB), Ok(AB), Ok(AB), Err(ABErr::NotEnoughTokens)]
1273        );
1274        assert_eq!(rest, vec!['a']);
1275    }
1276
1277    #[test]
1278    fn test_skip_many() {
1279        let mut t = "".into_tokens();
1280        let n_skipped = t.skip_many(|t| parse_ab(t).is_some());
1281        let rest: Vec<char> = t.collect();
1282        assert_eq!(n_skipped, 0);
1283        assert_eq!(rest, vec![]);
1284
1285        let mut t = "acabab".into_tokens();
1286        let n_skipped = t.skip_many(|t| parse_ab(t).is_some());
1287        let rest: Vec<char> = t.collect();
1288        assert_eq!(n_skipped, 0);
1289        assert_eq!(rest, vec!['a', 'c', 'a', 'b', 'a', 'b']);
1290
1291        let mut t = "ababaab".into_tokens();
1292        let n_skipped = t.skip_many(|t| parse_ab(t).is_some());
1293        let rest: Vec<char> = t.collect();
1294        assert_eq!(n_skipped, 2);
1295        assert_eq!(rest, vec!['a', 'a', 'b']);
1296    }
1297
1298    #[test]
1299    fn test_skip_many1() {
1300        let mut t = "".into_tokens();
1301        let res = t.skip_many1(parse_ab_err);
1302        let rest: String = t.collect();
1303        assert_eq!(res, Err(ABErr::NotEnoughTokens));
1304        assert_eq!(&*rest, "");
1305
1306        let mut t = "acabab".into_tokens();
1307        let res = t.skip_many1(parse_ab_err);
1308        let rest: String = t.collect();
1309        assert_eq!(res, Err(ABErr::IsNotB));
1310        assert_eq!(&*rest, "acabab");
1311
1312        let mut t = "abcbab".into_tokens();
1313        let res = t.skip_many1(parse_ab_err);
1314        let rest: String = t.collect();
1315        assert_eq!(res, Ok(1));
1316        assert_eq!(&*rest, "cbab");
1317
1318        let mut t = "ababcbab".into_tokens();
1319        let res = t.skip_many1(parse_ab_err);
1320        let rest: String = t.collect();
1321        assert_eq!(res, Ok(2));
1322        assert_eq!(&*rest, "cbab");
1323    }
1324
1325    #[test]
1326    fn test_parse_optimisations() {
1327        // Our test string.
1328        const S: &str = "345abc456";
1329
1330        fn parse_slice(mut tokens: impl Tokens<Item = char>) {
1331            // Get a start and end location to use:
1332            let from = tokens.location();
1333            tokens.take_while(|t| t.is_numeric()).consume();
1334            let to = tokens.location();
1335            tokens.set_location(from.clone());
1336
1337            // This should work (nothing will be consumed)
1338            let n = tokens
1339                .parse_slice::<u16, String>(from.clone(), to.clone())
1340                .unwrap();
1341            assert_eq!(n, 345);
1342            assert_eq!(tokens.collect::<String>(), S);
1343
1344            // reset location
1345            tokens.set_location(from.clone());
1346
1347            // This won't work (again nothing will be consumed)
1348            tokens.parse_slice::<u8, String>(from, to).unwrap_err();
1349            assert_eq!(tokens.collect::<String>(), S);
1350        }
1351
1352        fn parse_take_while(mut tokens: impl Tokens<Item = char>) {
1353            let start = tokens.location();
1354
1355            // This should work
1356            let n = tokens
1357                .parse_take_while::<u16, String, _>(|t| t.is_numeric())
1358                .unwrap();
1359            assert_eq!(n, 345);
1360            assert_eq!(tokens.collect::<String>(), "abc456");
1361
1362            // reset location
1363            tokens.set_location(start);
1364
1365            // This wont work and won't consume anything
1366            tokens
1367                .parse_take_while::<u8, String, _>(|t| t.is_numeric())
1368                .unwrap_err();
1369            assert_eq!(tokens.collect::<String>(), "345abc456");
1370        }
1371
1372        fn parse_take(mut tokens: impl Tokens<Item = char>) {
1373            let start = tokens.location();
1374
1375            // This should work
1376            let n = tokens.parse_take::<u16, String>(3).unwrap();
1377            assert_eq!(n, 345);
1378            assert_eq!(tokens.collect::<String>(), "abc456");
1379
1380            // reset location
1381            tokens.set_location(start);
1382
1383            // This wont work and won't consume anything
1384            tokens.parse_take::<u8, String>(3).unwrap_err();
1385            assert_eq!(tokens.collect::<String>(), "345abc456");
1386        }
1387
1388        // Test each method against our "optimised" StrTokens
1389        // and also the default impl of the methods via IterTokens
1390
1391        parse_slice(IterTokens::new(S.chars()));
1392        parse_slice(S.into_tokens());
1393
1394        parse_take_while(IterTokens::new(S.chars()));
1395        parse_take_while(S.into_tokens());
1396
1397        parse_take(IterTokens::new(S.chars()));
1398        parse_take(S.into_tokens());
1399    }
1400}