Parser

Trait Parser 

Source
pub trait Parser<'i>: Sized {
    type Output;
    type Then<T: Parser<'i>>: Then<'i, Self, T>;

Show 21 methods // Required method fn parse_ctx( &self, input: &'i [u8], state: &mut ParseState<'i>, commit: &mut bool, tail: bool, ) -> ParserResult<'i, Self::Output>; // Provided methods fn then<T: Parser<'i>>(self, next: T) -> Self::Then<T> { ... } fn or<T: Parser<'i, Output = Self::Output>>( self, alternative: T, ) -> Or<Self, T> { ... } fn commit(self) -> Commit<Self> { ... } fn map<O, F: Fn(Self::Output) -> O>(self, f: F) -> Map<Self, F> { ... } fn map_res<O, F: Fn(Self::Output) -> Result<O, &'static str>>( self, f: F, ) -> MapResult<Self, F> { ... } fn optional(self) -> Optional<Self> { ... } fn repeat_n<const N: usize, S: Parser<'i>>( self, separator: S, ) -> RepeatN<N, Self, S> where Self::Output: Copy + Default { ... } fn repeat_arrayvec<const N: usize, S: Parser<'i>>( self, separator: S, min_elements: usize, ) -> RepeatArrayVec<N, Self, S> where Self::Output: Copy + Default { ... } fn repeat<S: Parser<'i>>( self, separator: S, min_elements: usize, ) -> RepeatVec<Self, S> { ... } fn with_consumed(self) -> WithConsumed<Self> { ... } fn with_prefix<T: Parser<'i>>(self, prefix: T) -> WithPrefix<Self, T> { ... } fn with_suffix<T: Parser<'i>>(self, suffix: T) -> WithSuffix<Self, T> { ... } fn with_eol(self) -> WithSuffix<Self, Eol> { ... } fn error_msg(self, message: &'static str) -> WithErrorMsg<Self> { ... } fn parse_first( &self, input: &'i str, ) -> Result<(Self::Output, &'i [u8]), InputError> { ... } fn parse_complete(&self, input: &'i str) -> Result<Self::Output, InputError> { ... } fn parse_all(&self, input: &'i str) -> Result<Vec<Self::Output>, InputError> { ... } fn parse_lines( &self, input: &'i str, ) -> Result<Vec<Self::Output>, InputError> { ... } fn parse_iterator(self, input: &str) -> ParserIterator<'_, Self> { ... } fn matches_iterator(self, input: &str) -> ParserMatchesIterator<'_, Self> { ... }
}
Expand description

Trait implemented by all parsers.

Unlike Leaf parsers, parsers implementing this trait may handle branching and error recovery, including backtracking and commit.

Every Leaf parser is also a Parser via a blanket implementation.

Required Associated Types§

Source

type Output

Type of the value produced by parse when successful.

Source

type Then<T: Parser<'i>>: Then<'i, Self, T>

Type of the chained parser returned by then.

This is used to allow multiple then calls to extend one tuple, instead of nesting tuples inside each other.

Required Methods§

Source

fn parse_ctx( &self, input: &'i [u8], state: &mut ParseState<'i>, commit: &mut bool, tail: bool, ) -> ParserResult<'i, Self::Output>

Parse the provided bytes.

Returns a tuple of the successfully parsed Output value and the remaining bytes, or an ErrToken representing that an error was pushed into the provided ParseState.

Provided Methods§

Source

fn then<T: Parser<'i>>(self, next: T) -> Self::Then<T>

Sequence another parser after this one.

§Examples
assert!(matches!(
    parser::i32()
        .then(parser::i32())
        .parse_complete("123-123"),
    Ok((123, -123)),
));
Source

fn or<T: Parser<'i, Output = Self::Output>>(self, alternative: T) -> Or<Self, T>

Attempt to parse using this parser, followed by the provided parser.

The second parser will not be tried if the first parser commits.

See also parser::one_of.

§Examples
let parser = parser::u8()
    .map(|x| u32::from(x) * 1001001)
    .or(parser::u32());
assert!(matches!(
    parser.parse_complete("123"),
    Ok(123123123)
));
assert!(matches!(
    parser.parse_complete("1000"),
    Ok(1000)
));
Source

fn commit(self) -> Commit<Self>

Prevent backtracking past this parser if it succeeds and consumes input.

After committing, any later errors within the current alternative are treated as fatal, preventing the current innermost alternative parser from trying other branches.

This can be used to help ensure error messages are clear in cases where returning the furthest error from another branch would be misleading. It can also improve performance in error cases.

If this parser is not inside an alternative, this has no effect.

The following alternative parsers honor commit to prevent backtracking:

Source

fn map<O, F: Fn(Self::Output) -> O>(self, f: F) -> Map<Self, F>

Map the output of this parser using the supplied function.

§Examples
assert!(matches!(
    parser::u32()
        .map(|x| x * 2)
        .parse_complete("123"),
    Ok(246)
));

Closure that returns a value borrowing from both its input and an outer variable:

let my_string = String::from("123");
let my_vec = vec![4, 5, 6];
assert!(matches!(
    parser::take_while(u8::is_ascii_digit)
        .map(|x| (x, my_vec.as_slice()))
        .parse_complete(&my_string),
    Ok((&[b'1', b'2', b'3'], &[4, 5, 6]))
));
Source

fn map_res<O, F: Fn(Self::Output) -> Result<O, &'static str>>( self, f: F, ) -> MapResult<Self, F>

Map the output of this parser using the supplied fallible function.

Errors must be &'static str, which will be mapped to ParseError::Custom.

§Examples
let parser = parser::u8()
    .map_res(|x| x.checked_mul(2).ok_or("input too large"));
assert!(matches!(
    parser.parse_complete("123"),
    Ok(246)
));
assert_eq!(
    parser.parse_complete("200").unwrap_err().into_source(),
    ParseError::Custom("input too large"),
);

Closure that returns a value borrowing from both its input and an outer variable:

let my_string = String::from("123");
let my_vec = vec![4, 5, 6];
assert!(matches!(
    parser::take_while(u8::is_ascii_digit)
        .map_res(|x| {
            if x.len() < 10 {
                Ok((x, my_vec.as_slice()))
            } else {
                Err("expected fewer than 10 digits")
            }
        })
        .parse_complete(&my_string),
    Ok((&[b'1', b'2', b'3'], &[4, 5, 6]))
));
Source

fn optional(self) -> Optional<Self>

Wrap Output in Option, returning None on error unless the parser commits.

§Examples
let parser = parser::u32()
    .optional();
assert!(matches!(
    parser.parse_first("123"),
    Ok((Some(123), &[]))
));
assert!(matches!(
    parser.parse_first("abc"),
    Ok((None, &[b'a', b'b', b'c']))
));
Source

fn repeat_n<const N: usize, S: Parser<'i>>( self, separator: S, ) -> RepeatN<N, Self, S>
where Self::Output: Copy + Default,

Repeat this parser N times, returning an array.

If the number of items is variable use repeat_arrayvec or repeat.

§Examples
assert!(matches!(
    parser::u32()
        .repeat_n(",") // N = 3 is inferred
        .parse_complete("12,34,56"),
    Ok([12, 34, 56])
));
Source

fn repeat_arrayvec<const N: usize, S: Parser<'i>>( self, separator: S, min_elements: usize, ) -> RepeatArrayVec<N, Self, S>
where Self::Output: Copy + Default,

Repeat this parser while it matches, returning a ArrayVec.

This parser can parse up to N items. If more items match, it will return an error.

Returns error if the item parser commits and fails, or if the separator commits and then either it or the next item fails.

See repeat if the upper bound is large or not known, and repeat_n if the number of items is consistent.

§Examples
use utils::parser::{self, Parser};
let parser = parser::u32()
    .repeat_arrayvec::<5, _>(",", 3);
assert_eq!(
    parser.parse_first("12,34,56,78").unwrap(),
    (ArrayVec::from_slice(&[12, 34, 56, 78]).unwrap(), &b""[..])
);
assert_eq!(
    parser.parse_first("12,34,56,abc").unwrap(),
    (ArrayVec::from_slice(&[12, 34, 56]).unwrap(), &b",abc"[..])
);
assert!(parser.parse_first("12,34").is_err());
Source

fn repeat<S: Parser<'i>>( self, separator: S, min_elements: usize, ) -> RepeatVec<Self, S>

Repeat this parser while it matches, returning a Vec.

Returns error if the item parser commits and fails, or if the separator commits and then either it or the next item fails.

To avoid allocating, prefer repeat_n if the number of items is consistent and known in advance, or repeat_arrayvec if the number of items is variable but has a known upper bound.

§Examples
let parser = parser::u32()
    .repeat(",", 3);
assert_eq!(parser.parse_first("12,34,56,78").unwrap(), (vec![12, 34, 56, 78], &b""[..]));
assert_eq!(parser.parse_first("12,34,56,abc").unwrap(), (vec![12, 34, 56], &b",abc"[..]));
assert!(parser.parse_first("12,34").is_err());
Source

fn with_consumed(self) -> WithConsumed<Self>

Return the output of this parser as well as the bytes consumed.

This can be used to map any errors that occur while processing the parsed input back to the problematic item’s position in the input.

§Examples
assert_eq!(
    parser::u32().with_consumed().parse_first("012,345,678").unwrap(),
    ((12, &b"012"[..]), &b",345,678"[..])
);
Source

fn with_prefix<T: Parser<'i>>(self, prefix: T) -> WithPrefix<Self, T>

Parse a prefix (normally a string literal) before this parser.

The result of the prefix parser is discarded.

§Examples
assert_eq!(
    parser::u32()
        .with_prefix("abc")
        .parse_complete("abc123")
        .unwrap(),
    123,
);
Source

fn with_suffix<T: Parser<'i>>(self, suffix: T) -> WithSuffix<Self, T>

Parse a suffix (normally a string literal) after this parser.

The result of the suffix parser is discarded.

§Examples
assert_eq!(
    parser::u32()
        .with_suffix("abc")
        .parse_complete("123abc")
        .unwrap(),
    123,
);
Source

fn with_eol(self) -> WithSuffix<Self, Eol>

Parse a end of line (or end of string) after this parser.

Equivalent to parser.with_suffix(parser::eol()).

§Examples
assert_eq!(
    parser::u32()
        .with_eol()
        .parse_first("123\nabc")
        .unwrap(),
    (123, &b"abc"[..]),
);
Source

fn error_msg(self, message: &'static str) -> WithErrorMsg<Self>

Replace this parser’s error message with the provided string.

§Examples
let parser = parser::u8()
    .error_msg("expected power level");
assert_eq!(
    parser.parse_complete("123").unwrap(),
    123,
);
assert_eq!(
    parser.parse_complete("abc").unwrap_err().into_source(),
    ParseError::Custom("expected power level"),
);
Source

fn parse_first( &self, input: &'i str, ) -> Result<(Self::Output, &'i [u8]), InputError>

Apply this parser once, returning the parsed value and the remaining input or error.

This method should only be used to parse the first match and should not be called repeatedly to parse the remainder of the input, as the reported error positions will be incorrect.

§Examples
assert_eq!(parser::u32().parse_first("1234").unwrap(), (1234, &b""[..]));
assert_eq!(parser::u32().parse_first("123abc").unwrap(), (123, &b"abc"[..]));
assert!(parser::u32().parse_first("abc123").is_err());
Source

fn parse_complete(&self, input: &'i str) -> Result<Self::Output, InputError>

Apply this parser once, checking the provided input is fully consumed.

§Examples
assert_eq!(parser::u32().parse_complete("1234").unwrap(), 1234);
assert!(parser::u32().parse_complete("1234abc").is_err());
Source

fn parse_all(&self, input: &'i str) -> Result<Vec<Self::Output>, InputError>

Apply this parser repeatedly until the provided input is fully consumed.

Equivalent to parser.repeat(parser::noop(), 0).parse_complete(input).

§Examples
assert_eq!(
    parser::u32()
        .then(parser::u32().with_prefix("x"))
        .with_suffix(",".or(parser::eof()))
        .parse_all("1x2,3x4,1234x5678")
        .unwrap(),
    vec![
        (1, 2),
        (3, 4),
        (1234, 5678),
    ]
);
Source

fn parse_lines(&self, input: &'i str) -> Result<Vec<Self::Output>, InputError>

Similar to parse_all but expects a newline between each item.

§Examples
assert_eq!(
    parser::u32()
        .then(parser::u32().with_prefix("x"))
        .parse_lines("1x2\n3x4\n1234x5678")
        .unwrap(),
    vec![
        (1, 2),
        (3, 4),
        (1234, 5678),
    ]
);
Source

fn parse_iterator(self, input: &str) -> ParserIterator<'_, Self>

Create an iterator which applies this parser repeatedly until the provided input is fully consumed.

The returned iterator will lazily parse the provided input string, producing a sequence of Result values. Once the end of input is reached, or an error is returned, the parser will always return None.

§Examples
let iterator = parser::u32()
    .with_eol()
    .parse_iterator("12\n34\n56\n78");
for item in iterator {
    println!("{}", item?);
}
let mut iterator = parser::u32()
    .with_eol()
    .parse_iterator("12\n34\nnot a integer");
assert_eq!(iterator.next().unwrap().unwrap(), 12);
assert_eq!(iterator.next().unwrap().unwrap(), 34);
assert!(iterator.next().unwrap().is_err());
assert!(iterator.next().is_none());
let filtered = parser::u32()
    .with_eol()
    .parse_iterator("11\n22\n33\n44\n55")
    .filter(|r| r.is_err() || r.as_ref().is_ok_and(|v| v % 2 == 0))
    .collect::<Result<Vec<u32>, InputError>>()?;
assert_eq!(filtered, vec![22, 44]);
Source

fn matches_iterator(self, input: &str) -> ParserMatchesIterator<'_, Self>

Create an iterator which returns matches only and skips over errors.

This is intended for cases that require extracting matches out of the input. Otherwise, parse_iterator should be used with a parser that can match the entire input structure.

§Examples
assert_eq!(
    parser::u32()
        .matches_iterator("abc123d456efg7hi8jk9lmnop")
        .collect::<Vec<_>>(),
    vec![123, 456, 7, 8, 9]
);

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<'i, L: Leaf<'i>> Parser<'i> for L

Source§

type Output = <L as Leaf<'i>>::Output

Source§

type Then<T: Parser<'i>> = Then2<L, T>