// use std::rc::Rc as RcOrArc; use std::sync::Arc as RcOrArc; fn main() { assert_eq!( Query::select() .columns([Char::Character, Char::SizeW, Char::SizeH]) .from(Char::Table) .to_string(), "" ); } #[derive(Debug)] pub enum Character { Table, Id, Character, FontSize, SizeW, SizeH, FontId, Ascii, CreatedAt, UserData, } pub type Char = Character; impl Iden for Character { fn unquoted(&self, s: &mut dyn std::fmt::Write) { write!( s, "{}", match self { Self::Table => "character", Self::Id => "id", Self::Character => "character", Self::FontSize => "font_size", Self::SizeW => "size_w", Self::SizeH => "size_h", Self::FontId => "font_id", Self::Ascii => "ascii", Self::CreatedAt => "created_at", Self::UserData => "user_data", } ) .unwrap(); } } pub struct Query; impl Query { pub fn select() -> SelectStatement { SelectStatement::new() } } pub struct SelectStatement { pub(crate) selects: Vec, pub(crate) from: Vec, } impl SelectStatement { /// Construct a new [`SelectStatement`] pub fn new() -> Self { Self { selects: vec![], from: vec![], } } pub fn columns(&mut self, cols: I) -> &mut Self where T: IntoColumnRef, I: IntoIterator, { self.exprs( cols.into_iter() .map(|c| SimpleExpr::Column(c.into_column_ref())) .collect::>(), ) } pub fn exprs(&mut self, exprs: I) -> &mut Self where T: Into, I: IntoIterator, { self.selects .append(&mut exprs.into_iter().map(|c| c.into()).collect()); self } pub fn from(&mut self, tbl_ref: R) -> &mut Self where R: IntoTableRef, { self.from_from(tbl_ref.into_table_ref()) } fn from_from(&mut self, select: TableRef) -> &mut Self { self.from.push(select); self } fn to_string(&self) -> String { "".into() } } pub struct SelectExpr { pub expr: SimpleExpr, } impl From for SelectExpr where T: Into, { fn from(expr: T) -> Self { SelectExpr { expr: expr.into() } } } pub enum SimpleExpr { Column(ColumnRef), } pub enum ColumnRef { Column(DynIden), } pub trait IntoColumnRef { fn into_column_ref(self) -> ColumnRef; } impl IntoColumnRef for T where T: IntoIden, { fn into_column_ref(self) -> ColumnRef { ColumnRef::Column(self.into_iden()) } } pub enum TableRef { Table(DynIden), } pub trait IntoTableRef { fn into_table_ref(self) -> TableRef; } impl IntoTableRef for T where T: IntoIden, { fn into_table_ref(self) -> TableRef { TableRef::Table(self.into_iden()) } } pub type DynIden = SeaRc; #[repr(transparent)] pub struct SeaRc(pub(crate) RcOrArc) where I: ?Sized; impl SeaRc { pub fn new(i: I) -> SeaRc where I: Iden + 'static, { SeaRc(RcOrArc::new(i)) } } pub trait IntoIden { fn into_iden(self) -> DynIden; } impl IntoIden for T where T: Iden, { fn into_iden(self) -> DynIden { SeaRc::new(self) } } pub trait Iden { fn unquoted(&self, s: &mut dyn std::fmt::Write); }