pub enum Keyword {
Select {
table: String,
fields: Vec<String>
},
Insert {
table: String,
fields: Vec<(String, String)>,
},
Filter {
fields: Vec<(String, String)>,
}
}
pub struct Query {
pub keywords: Vec<Keyword>
}
impl Query {
pub fn new() -> Self {
Query { keywords: Vec::new() }
}
pub fn select<T: Into<String> + std::fmt::Display>(&mut self, table: T, values: Vec<T>) -> &mut Self {
self.keywords.push(Keyword::Select { table: table.into(), fields: values.iter().map(|e| e.to_string()).collect::<Vec<String>>() });
return self
}
pub fn filter(&mut self, fields: Vec<(String, String)>) -> &mut Self {
self.keywords.push(Keyword::Filter { fields });
return self
}
pub fn insert<T: Into<String> + std::fmt::Display>(&mut self, table: T, fields: Vec<(String, String)>) -> &mut Self {
self.keywords.push(Keyword::Insert { table: table.into(), fields });
return self
}
pub fn build(&self) -> String {
let mut query = String::new();
for keyword in &self.keywords {
match keyword {
Keyword::Select { table, fields } => {
query.push_str(&format!("select {table} {{ {} }}", fields.join(",")))
},
Keyword::Insert { table, fields } => {
query.push_str(&format!("insert {table} {{ {} }}", fields.iter().map(|f| format!("{} := \"{}\"", f.0, f.1)).collect::<Vec<String>>().join(",")))
}
Keyword::Filter { fields } => {
let mut filter_stmt = String::from("filter");
let filters = fields.iter().map(|f| format!(".{} = \"{}\"", f.0, f.1)).collect::<Vec<String>>().join("and");
filter_stmt.push_str(&filters);
query.push_str(&filter_stmt);
}
}
}
query.push(';');
return query
}
}
#[cfg(test)]
mod query_tests {
#[test]
fn basic_query() {
let mut query = crate::Query::new();
query.select("movie".to_string(), vec!["title".to_string()]);
let query_str = query.build();
assert_eq!(query_str, String::from("select movie { title }"));
}
}