Skip to main content

axfive_matrix_dicebot/commands/
parser.rs

1use nom::{complete, named, tag, take_while, tuple, IResult};
2
3use crate::commands::{Command, RollCommand};
4use crate::dice::parser::parse_element_expression;
5use crate::parser::eat_whitespace;
6
7// Parse a roll expression.
8fn parse_roll(input: &str) -> IResult<&str, Box<dyn Command>> {
9    let (input, _) = eat_whitespace(input)?;
10    let (input, expression) = parse_element_expression(input)?;
11    Ok((input, Box::new(RollCommand(expression))))
12}
13
14/// Potentially parse a command expression.  If we recognize the command, an error should be raised
15/// if the command is misparsed.  If we don't recognize the command, ignore it and return none
16pub fn parse_command(original_input: &str) -> IResult<&str, Option<Box<dyn Command>>> {
17    let (input, _) = eat_whitespace(original_input)?;
18    named!(command(&str) -> (&str, &str), tuple!(complete!(tag!("!")), complete!(take_while!(char::is_alphabetic))));
19    let (input, command) = match command(input) {
20        // Strip the exclamation mark
21        Ok((input, (_, result))) => (input, result),
22        Err(_e) => return Ok((original_input, None)),
23    };
24    match command {
25        "r" | "roll" => parse_roll(input).map(|(input, command)| (input, Some(command))),
26        // No recognized command, ignore this.
27        _ => Ok((original_input, None)),
28    }
29}