83 lines
2.7 KiB
Rust
83 lines
2.7 KiB
Rust
use std::collections::VecDeque;
|
|
|
|
use crate::{
|
|
command::{Command, CommandParseError},
|
|
statements::Statement,
|
|
tokens::tokenize,
|
|
};
|
|
|
|
pub fn parse(file: String, input: String) -> Result<Vec<Command>, Vec<CommandParseError>> {
|
|
let mut tokens: VecDeque<_> = tokenize(input, file)
|
|
.map_err(|x| x.into_iter().map(|x| x.into()).collect::<Vec<_>>())?
|
|
.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("<stdin>");
|
|
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("<stdin>");
|
|
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("<stdin>");
|
|
assert_debug_snapshot!(parse(
|
|
file.clone(),
|
|
String::from(".exit select select insert select")
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn test_parse_multiple_incorrect() {
|
|
let file = String::from("<stdin>");
|
|
assert_debug_snapshot!(parse(
|
|
file.clone(),
|
|
String::from(".halp salect selact inset seiect")
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn test_parse_multiple_mixed() {
|
|
let file = String::from("<stdin>");
|
|
assert_debug_snapshot!(parse(
|
|
file.clone(),
|
|
String::from(".exit selct select nsert select")
|
|
));
|
|
}
|
|
}
|