use std::collections::VecDeque; use crate::{ command::{Command, CommandParseError}, statements::Statement, tokens::tokenize, }; pub fn parse(file: String, input: String) -> Result, Vec> { let mut tokens: VecDeque<_> = tokenize(input, file) .map_err(|x| x.into_iter().map(|x| x.into()).collect::>())? .into(); let mut cmds = Vec::new(); let errs = Vec::new(); while let Some(token) = tokens.pop_front() { match token.data { crate::tokens::TokenData::Insert => cmds.push(Command::Statement(Statement::Insert)), crate::tokens::TokenData::Select => cmds.push(Command::Statement(Statement::Select)), crate::tokens::TokenData::MetaCommand(meta_command) => { cmds.push(Command::MetaCommand(meta_command)) } crate::tokens::TokenData::EndOfFile => (), } } if errs.is_empty() { Ok(cmds) } else { Err(errs) } } #[cfg(test)] mod tests { use super::*; use insta::assert_debug_snapshot; #[test] fn test_parse_single_correct() { let file = String::from(""); assert_debug_snapshot!(parse(file.clone(), String::from(".exit"))); assert_debug_snapshot!(parse(file.clone(), String::from("select"))); assert_debug_snapshot!(parse(file.clone(), String::from("sElEcT"))); assert_debug_snapshot!(parse(file.clone(), String::from("INSERT"))); assert_debug_snapshot!(parse(file.clone(), String::from("InSErT"))); } #[test] fn test_parse_single_incorrect() { let file = String::from(""); assert_debug_snapshot!(parse(file.clone(), String::from(".halp"))); assert_debug_snapshot!(parse(file.clone(), String::from("salect"))); assert_debug_snapshot!(parse(file.clone(), String::from("sAlEcT"))); assert_debug_snapshot!(parse(file.clone(), String::from("INSART"))); assert_debug_snapshot!(parse(file.clone(), String::from("InSArT"))); } #[test] fn test_parse_multiple_correct() { let file = String::from(""); assert_debug_snapshot!(parse( file.clone(), String::from(".exit select select insert select") )); } #[test] fn test_parse_multiple_incorrect() { let file = String::from(""); assert_debug_snapshot!(parse( file.clone(), String::from(".halp salect selact inset seiect") )); } #[test] fn test_parse_multiple_mixed() { let file = String::from(""); assert_debug_snapshot!(parse( file.clone(), String::from(".exit selct select nsert select") )); } }