Parse

Trait Parse 

Source
pub trait Parse: Parser {
    // Provided methods
    fn parse(tokens: &mut TokenIter) -> Result<Self, Error> { ... }
    fn parse_all(tokens: &mut TokenIter) -> Result<Self, Error> { ... }
    fn parse_with<T>(
        tokens: &mut TokenIter,
        f: impl FnOnce(Self, &mut TokenIter) -> Result<T, Error>,
    ) -> Result<T, Error> { ... }
}
Expand description

This trait provides the user facing API to parse grammatical entities. It is implemented for anything that implements the Parser trait. The methods here encapsulating the iterator that is used for parsing into a transaction. This iterator is always Clone. Instead using a peekable iterator or implementing deeper peeking, parse clones this iterator to make access transactional, when parsing succeeds then the transaction becomes committed, otherwise it is rolled back.

This trait cannot be implemented by user code.

Provided Methods§

Source

fn parse(tokens: &mut TokenIter) -> Result<Self, Error>

This is the user facing API to parse grammatical entities. Calls a parser() within a transaction. Commits changes on success and returns the parsed value.

§Errors

When the parser returns an error the transaction is rolled back and the error is returned.

Source

fn parse_all(tokens: &mut TokenIter) -> Result<Self, Error>

Exhaustive parsing within a transaction. This is a convenience method that implies a EndOfStream at the end. Thus it will error if parsing is not exhaustive.

§Errors

When the parser returns an error or there are tokens left in the stream the transaction is rolled back and a error is returned.

Source

fn parse_with<T>( tokens: &mut TokenIter, f: impl FnOnce(Self, &mut TokenIter) -> Result<T, Error>, ) -> Result<T, Error>

Parse a value in a transaction, pass it to a FnOnce(Self, &mut TokenIter) -> Result<T> closure which creates a new result or returns an Error.

This method is a very powerful tool as it allows anything from simple validations to complete transformations into a new type. You may find this useful to implement parsers for complex types that need some runtime logic.

The closures first argument is the parsed value and the second argument is the transactional iterator pointing after parsing Self. This can be used to create errors or parse further. In many cases it can be ignored with _.

§Using with the unsynn! macro

The [unsynn!] macro provides convenient syntax sugar for this method via the parse_with clause. See the macro documentation for details.

unsynn! {
    struct PositiveInt(LiteralInteger);
    parse_with |this, tokens| {
        if this.0.value() > 0 {
            Ok(this)
        } else {
            Error::other(None, tokens, "must be positive".into())
        }
    };
}
§Example
// A parser that parses a comma delimited list of anything but commas
// and stores these lexical sorted.
struct OrderedStrings {
    strings: Vec<String>
}

impl Parser for OrderedStrings {
    fn parser(tokens: &mut TokenIter) -> Result<Self> {
        // Our input is CommaDelimitedVec<String>, we'll transform that into
        // OrderedStrings.
        Parse::parse_with(tokens, |this : CommaDelimitedVec<String>, _| -> Result<OrderedStrings> {
            let mut strings: Vec<String> = this.into_iter()
                .map(|s| s.value)
                .collect();
            strings.sort();
            Ok(OrderedStrings { strings })
        })
    }
}
let mut input = "a, d, b, e, c,".to_token_iter();
let ordered_strings: OrderedStrings = input.parse().unwrap();
assert_eq!(ordered_strings.strings, vec!["a", "b", "c", "d", "e"]);
§Errors

When the parser or the closure returns an error, the transaction is rolled back and the error is returned.

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<T> Parse for T
where T: Parser,

Parse is implemented for anything that implements Parser.