From c568c9d38fafe61ae043b69b0aa7a998b142448b Mon Sep 17 00:00:00 2001 From: Arnaud Bailly Date: Tue, 24 Sep 2024 09:45:29 +0200 Subject: Tokenize a sequence of whitespace separated values --- rust/src/parser.rs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'rust/src/parser.rs') diff --git a/rust/src/parser.rs b/rust/src/parser.rs index 6b18a9d..b3d76fb 100644 --- a/rust/src/parser.rs +++ b/rust/src/parser.rs @@ -1,11 +1,20 @@ use crate::ast::*; pub fn parse(arg: &str) -> Value { - let token = arg.trim(); - parse_number(token) - .or(parse_bool(token)) - .or(parse_symbol(token)) - .unwrap() + if let Some(token) = tokenize(arg).first() { + return parse_number(token) + .or(parse_bool(token)) + .or(parse_symbol(token)) + .unwrap(); + } + panic!("No value to parse"); +} + +fn tokenize(arg: &str) -> Vec { + arg.split(|c: char| c.is_whitespace()) + .filter(|s| !s.is_empty()) + .map(|s| s.to_string()) + .collect() } fn parse_symbol(token: &str) -> Result { @@ -28,8 +37,8 @@ fn parse_number(token: &str) -> Result { #[cfg(test)] mod tests { - use super::parse; use super::Value::*; + use super::{parse, tokenize}; use proptest::prelude::*; proptest! { @@ -57,4 +66,9 @@ mod tests { assert_eq!(Sym("foo".to_string()), parse(" foo \n\r")); assert_eq!(Num(-42), parse("\n-42")); } + + #[test] + fn tokenize_several_values() { + assert_eq!(vec!["42", "foo", "true"], tokenize("42 foo \ntrue ")); + } } -- cgit v1.2.3