96 lines
2.8 KiB
Rust
96 lines
2.8 KiB
Rust
|
use std::io::Write;
|
||
|
use std::mem::size_of;
|
||
|
|
||
|
pub enum StatementType {
|
||
|
Insert {
|
||
|
row: Row
|
||
|
},
|
||
|
Select,
|
||
|
}
|
||
|
|
||
|
const COLUMN_USERNAME_SIZE: usize = 32;
|
||
|
const COLUMN_EMAIL_SIZE: usize = 255;
|
||
|
|
||
|
pub struct Row {
|
||
|
id: u32,
|
||
|
username: [u8; COLUMN_USERNAME_SIZE],
|
||
|
email: [u8; COLUMN_EMAIL_SIZE],
|
||
|
}
|
||
|
|
||
|
impl Row {
|
||
|
fn new(id: u32, username: String, email: String) -> Result<Self, String> {
|
||
|
let username_bytes = username.as_bytes();
|
||
|
let email_bytes = email.as_bytes();
|
||
|
if username_bytes.len() > COLUMN_USERNAME_SIZE {
|
||
|
Err(String::from("username is too long"))
|
||
|
} else if email_bytes.len() > COLUMN_EMAIL_SIZE {
|
||
|
Err(String::from("email is too long"))
|
||
|
} else {
|
||
|
let username_buffer = &mut [0; COLUMN_USERNAME_SIZE];
|
||
|
if let Err(_) = pad_buffer(username_buffer, username_bytes) {
|
||
|
panic!("could not pad username buffer")
|
||
|
}
|
||
|
let email_buffer = &mut [0; COLUMN_EMAIL_SIZE];
|
||
|
if let Err(_) = pad_buffer(email_buffer, username_bytes) {
|
||
|
panic!("could not pad username buffer")
|
||
|
}
|
||
|
Ok(Self {
|
||
|
id,
|
||
|
username: *username_buffer,
|
||
|
email: *email_buffer,
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn pad_buffer(mut bytes: &mut [u8], source: &[u8]) -> std::io::Result<usize> {
|
||
|
bytes.write(source)
|
||
|
}
|
||
|
|
||
|
pub struct Statement {
|
||
|
statement_type: StatementType,
|
||
|
}
|
||
|
|
||
|
impl Statement {
|
||
|
pub fn new(statement_type: StatementType) -> Self {
|
||
|
Self {
|
||
|
statement_type,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn parse_statement(command: &String) -> Result<Self, String> {
|
||
|
if command.starts_with("insert") {
|
||
|
match sscanf::scanf!(command, "insert {} {} {}", usize, str, str) {
|
||
|
Ok((id, username, email)) => {
|
||
|
match Row::new(u32::try_from(id).unwrap(), username.to_string(), email.to_string()) {
|
||
|
Ok(row) => {
|
||
|
Ok(Statement::new(StatementType::Insert { row: row }))
|
||
|
}
|
||
|
Err(e) => { Err(e) }
|
||
|
}
|
||
|
}
|
||
|
_ => {
|
||
|
Err(String::from("could not parse insert statement"))
|
||
|
}
|
||
|
}
|
||
|
} else if command.starts_with("select") {
|
||
|
Ok(Statement::new(StatementType::Select))
|
||
|
} else {
|
||
|
return Err(String::from("Could not parse command"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub(crate) fn execute(&self) {
|
||
|
match &self.statement_type {
|
||
|
StatementType::Insert { row } => {
|
||
|
println!("This is where you do an insert {}", row.id)
|
||
|
}
|
||
|
StatementType::Select => {
|
||
|
println!("This is where you do an select")
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|