From a7876f76bf9935930ec78edb73cfe650e415389b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kha=C3=AFs=20COLIN?= Date: Thu, 1 May 2025 22:19:24 +0200 Subject: [PATCH] feat(osdb): parse insert and select statements --- src/main.rs | 120 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index 51c4b5f..69e14a3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,28 +29,138 @@ impl std::str::FromStr for MetaCommand { } } +enum Statement { + Insert, + Select, +} + +enum StatementParseError { + Unrecognized { stmt: String }, +} + +impl std::fmt::Display for StatementParseError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + StatementParseError::Unrecognized { stmt } => { + write!(f, "unrecognized statement {stmt:?}") + } + } + } +} + +impl std::str::FromStr for Statement { + type Err = StatementParseError; + + fn from_str(s: &str) -> Result { + let s = s.trim(); + let lower = s.to_lowercase(); + if lower.starts_with("insert") { + Ok(Statement::Insert) + } else if lower.starts_with("select") { + Ok(Statement::Select) + } else { + Err(StatementParseError::Unrecognized { + stmt: s.to_string(), + }) + } + } +} + +enum Command { + MetaCommand(MetaCommand), + Statement(Statement), +} + +enum CommandParseError { + MetaCommand(MetaCommandParseError), + Statement(StatementParseError), +} + +impl std::fmt::Display for CommandParseError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + CommandParseError::MetaCommand(meta_command_parse_error) => { + write!(f, "{meta_command_parse_error}") + } + CommandParseError::Statement(statement_parse_error) => { + write!(f, "{statement_parse_error}") + } + } + } +} + +impl From for Command { + fn from(value: MetaCommand) -> Self { + Command::MetaCommand(value) + } +} + +impl From for CommandParseError { + fn from(value: MetaCommandParseError) -> Self { + CommandParseError::MetaCommand(value) + } +} + +impl From for Command { + fn from(value: Statement) -> Self { + Command::Statement(value) + } +} + +impl From for CommandParseError { + fn from(value: StatementParseError) -> Self { + CommandParseError::Statement(value) + } +} + +impl std::str::FromStr for Command { + type Err = CommandParseError; + + fn from_str(s: &str) -> Result { + if s.starts_with(".") { + s.parse::() + .map(|x| x.into()) + .map_err(|x| x.into()) + } else { + s.parse::() + .map(|x| x.into()) + .map_err(|x| x.into()) + } + } +} + fn main() { startup_msg(); while let Some(input) = read_input() { match input.parse() { Ok(cmd) => match cmd { - MetaCommand::Exit => { - println!("Good-bye"); - break; - } + Command::MetaCommand(cmd) => match cmd { + MetaCommand::Exit => { + println!("Good-bye"); + break; + } + }, + Command::Statement(stmt) => execute_statment(stmt), }, Err(err) => eprintln!("{err}"), } } } +fn execute_statment(stmt: Statement) { + match stmt { + Statement::Insert => println!("insert"), + Statement::Select => println!("select"), + } +} + fn startup_msg() { let name = env!("CARGO_PKG_NAME"); let version = env!("CARGO_PKG_VERSION"); let authors = env!("CARGO_PKG_AUTHORS"); println!("{name} v{version} started.",); - println!("Copyright 2024 {authors}. All rights reserved.") + println!("Copyright 2025 {authors}. All rights reserved.") } fn read_input() -> Option {