tenebrous-dicebot/src/commands/parser.rs

35 lines
1.4 KiB
Rust
Raw Normal View History

2020-04-21 06:11:52 +00:00
use nom::{complete, named, tag, take_while, tuple, IResult};
use crate::commands::{Command, RollCommand};
use crate::dice::parser::parse_element_expression;
2020-04-21 06:09:43 +00:00
use crate::parser::eat_whitespace;
// Parse a roll expression.
2020-04-21 06:07:03 +00:00
fn parse_roll(input: &str) -> IResult<&str, RollCommand> {
let (input, _) = eat_whitespace(input)?;
let (input, expression) = parse_element_expression(input)?;
2020-04-21 06:07:03 +00:00
Ok((input, RollCommand(expression)))
}
2020-04-21 06:07:03 +00:00
// Potentially parse a command expression. If we recognize the command, an error should be raised
// if the command is misparsed. If we don't recognize the command, ignore it.
pub fn parse_command(original_input: &str) -> IResult<&str, Option<Box<dyn Command>>> {
let (input, _) = eat_whitespace(original_input)?;
named!(command(&str) -> (&str, &str), tuple!(complete!(tag!("!")), complete!(take_while!(char::is_alphabetic))));
let (input, command) = match command(input) {
// Strip the exclamation mark
Ok((input, (_, result))) => (input, result),
2020-04-21 06:09:43 +00:00
Err(_e) => return Ok((original_input, None)),
2020-04-21 06:07:03 +00:00
};
2020-04-21 06:08:29 +00:00
let (input, command) = match command {
2020-04-21 06:07:03 +00:00
"r" | "roll" => {
let (input, command) = parse_roll(input)?;
let command: Box<dyn Command> = Box::new(command);
(input, command)
2020-04-21 06:09:43 +00:00
}
2020-04-21 06:07:03 +00:00
// No recognized command, ignore this.
_ => return Ok((original_input, None)),
};
Ok((input, Some(command)))
}