Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use nom::is_alphabetic;
- use std::str;
- #[derive(Debug, PartialEq, Eq)]
- pub enum Keyword {
- Unknown,
- Help,
- Echo,
- }
- #[derive(Debug, PartialEq, Eq)]
- pub enum Command {
- Unknown,
- Help,
- Echo(String),
- }
- fn to_keyword(s: &[u8]) -> Keyword {
- if compare_no_case(&s, b"help") {
- return Keyword::Help;
- } else if compare_no_case(&s, b"echo") {
- return Keyword::Echo;
- }
- Keyword::Unknown
- }
- fn is_argument_char(i: u8) -> bool {
- !b"\r\n".contains(&i)
- }
- pub fn to_command(keyword: Keyword, argument: &[u8]) -> Command {
- match keyword {
- Keyword::Unknown => Command::Unknown,
- Keyword::Help => Command::Help,
- Keyword::Echo => Command::Echo(str::from_utf8(argument).unwrap().into()),
- }
- }
- fn is_token_char(i: u8) -> bool {
- is_alphabetic(i) || b"_-".contains(&i)
- }
- pub fn compare_no_case(left: &[u8], right: &[u8]) -> bool {
- if left.len() != right.len() {
- return false;
- }
- left.iter().zip(right).all(|(a, b)| match (*a, *b) {
- (0...64, 0...64) | (91...96, 91...96) | (123...255, 123...255) => a == b,
- (65...90, 65...90) | (97...122, 97...122) | (65...90, 97...122) | (97...122, 65...90) => {
- *a | 0b00_10_00_00 == *b | 0b00_10_00_00
- }
- _ => false,
- })
- }
- named!(eoc, alt!(tag!("\n") | tag!("\r\n")));
- named!(space, alt!(tag!(" ") | tag!("\t")));
- named!(keyword<&[u8], Keyword>, map!(take_while!(is_token_char), to_keyword));
- named!(argument, take_while!(is_argument_char));
- named!(command<&[u8], Command>,
- do_parse!(
- tag!("!") >>
- keyword: keyword >>
- opt!(space) >>
- argument: argument >>
- eoc >>
- (to_command(keyword, argument))
- )
- );
- pub fn parse(input: &str) -> Result<Command, nom::Err<&[u8]>> {
- let result = command(input.as_bytes())?;
- Ok(result.1)
- }
- #[cfg(test)]
- mod tests {
- use crate::parser::*;
- #[test]
- fn parse_command_with_crlf() {
- assert_eq!(parse("!help\r\n"), Ok(Command::Help));
- }
- #[test]
- fn parse_command_with_lf() {
- assert_eq!(parse("!help\n"), Ok(Command::Help));
- }
- #[test]
- fn parse_unknown_command() {
- assert_eq!(parse("!omg\n"), Ok(Command::Unknown));
- }
- #[test]
- fn parse_command_with_argument() {
- assert_eq!(parse("!echo omg\n"), Ok(Command::Echo("omg".into())));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement