fn main() { let input = "123 world"; println!("source: {}, parsed: {:?}", input, source(input)); let input = "Hello world"; println!("source: {}, parsed: {:?}", input, source(input)); let input = " world"; println!("source: {}, parsed: {:?}", input, source(input)); } fn source(mut input: &str) -> Vec<Token> { let mut tokens = vec![]; while !input.is_empty() { input = if let (next_input, Some(token)) = token(input) { tokens.push(token); next_input } else { break; } } tokens } #[derive(Debug, PartialEq, Eq)] enum Token { Ident, Number, } fn token(i: &str) -> (&str, Option<Token>) { if let (i, Some(ident_res)) = ident(whitespace(i)) { return (i, Some(ident_res)); } if let (i, Some(number_res)) = number(whitespace(i)) { return (i, Some(number_res)); } (i, None) } fn whitespace(mut input: &str) -> &str { while matches!(input.chars().next(), Some(' ')) { let mut chars = input.chars(); chars.next(); input = chars.as_str(); } input } fn ident(mut input: &str) -> (&str, Option<Token>) { if matches!( input.chars().next(), Some(_x @ ('a'..='z' | 'A'..='Z')) ) { while matches!( input.chars().next(), Some(_x @ ('a'..='z' | 'A'..='Z' | '0'..='9')) ) { let mut chars = input.chars(); chars.next(); input = chars.as_str(); } (input, Some(Token::Ident)) } else { (input, None) } } fn number(mut input: &str) -> (&str, Option<Token>) { if matches!( input.chars().next(), Some(_x @ ('-'|'+'|'.'|'0'..='9')) ) { while matches!( input.chars().next(), Some(_x @ ('.'|'0'..='9')) ) { let mut chars = input.chars(); chars.next(); input = chars.as_str(); } (input, Some(Token::Number)) } else { (input, None) } } #[cfg(test)] mod test { use super::*; #[test] fn test_whitespace() { assert_eq!(whitespace(" "), ""); } #[test] fn test_indent() { assert_eq!(ident("Adam"), ""); } #[test] fn test_number() { assert_eq!(number("123.45 "), " "); } }
Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.04s
Running `target/debug/ruscal`
source: 123 world, parsed: [Number, Ident]
source: Hello world, parsed: [Ident, Ident]
source: world, parsed: [Ident]