trivet 3.1.0

The trivet Parser Library
Documentation
fn parse_unsigned_integer(parser: &mut trivet::Parser) -> trivet::errors::ParseResult<u64> {
    let result = parser.take_while(|ch| ch.is_ascii_digit());
    match result.parse::<u64>() {
        Ok(number) => Ok(number),
        Err(err) => Err(trivet::errors::error(parser.loc(), err)),
    }
}

fn parse_identifier(parser: &mut trivet::Parser) -> String {
    let mut result = parser.take_while(|ch| ch.is_alphabetic());
    result += parser.take_while(|ch| ch.is_alphanumeric()).as_str();
    result
}

#[derive(Debug)]
enum Thing {
    Number(trivet::Loc, u64),
    Id(trivet::Loc, String),
}

fn parse_sequence_ws(parser: &mut trivet::Parser) -> trivet::errors::ParseResult<Vec<Thing>> {
    let mut things = Vec::new();
    let _ = parser.consume_ws();
    while !parser.is_at_eof() {
        match parser.peek() {
            ch if ch.is_ascii_digit() => {
                things.push(Thing::Number(parser.loc(), parse_unsigned_integer(parser)?));
            }
            ch if ch.is_alphabetic() => {
                things.push(Thing::Id(parser.loc(), parse_identifier(parser)));
            }
            ch => {
                return Err(trivet::errors::unexpected_text_error(
                    parser.loc(),
                    "number or identifier",
                    &ch.to_string(),
                ));
            }
        }
        let _ = parser.consume_ws();
    }
    Ok(things)
}

fn main() {
    let mut parser = trivet::parse_from_stdin();
    match parse_sequence_ws(&mut parser) {
        Err(err) => {
            println!("{}", err);
        }
        Ok(seq) => {
            for thing in seq {
                match thing {
                    Thing::Number(loc, value) => {
                        println!("{}: number = {}", loc, value)
                    }
                    Thing::Id(loc, ident) => {
                        println!("{}: identifier = {}", loc, ident)
                    }
                }
            }
        }
    }
}