use nom::{ IResult, Parser, branch::alt, bytes::complete::{tag, take_while}, character::complete::multispace1, }; #[derive(Debug,PartialEq)] pub enum Token { ParOpen, ParClose, Num(i32), Sym(String), Whitespace(String), } use Token::*; use crate::parse::util::*; fn parse_token(s: &str) -> IResult<&str, Token> { alt(( tag("(").map(|_| ParOpen), tag(")").map(|_| ParClose), multispace1.map(whitespace), nom::character::complete::i32.map(Num), take_while(|c| !(" \n\t()".contains(c))).map(sym), )).parse(s) } #[cfg(test)] mod private_parsing_tests { use super::{*, parse_token}; #[test] fn test_parse_token() { assert_eq!(parse_token("()"), Ok((")", ParOpen))); assert_eq!(parse_token(")"), Ok(("", ParClose))); assert_eq!(parse_token(" \t\n"), Ok(("", whitespace(" \t\n")))); assert_eq!(parse_token("1 23"), Ok((" 23", Num(1)))); assert_eq!(parse_token("23"), Ok(("", Num(23)))); assert_eq!(parse_token("Nil a"), Ok((" a", sym("Nil")))); assert_eq!(parse_token("a"), Ok(("", sym("a")))); } }