use proc_macro::TokenStream;
use quote::{format_ident, quote};
use syn::{parse_macro_input, DeriveInput};
use syn::parse::{Parse,ParseStream};
use std::rc::Rc;
mod kw {
syn::custom_keyword!(SELECT);
syn::custom_keyword!(FROM);
syn::custom_keyword!(WHERE);
}
enum Expr {
Column(syn::Ident),
Constant,
Placeholder(&'static str),
And(Rc<Expr>, Rc<Expr>),
Or(Rc<Expr>, Rc<Expr>),
Equal(Rc<Expr>, Rc<Expr>),
}
impl Parse for Expr {
fn parse(input: ParseStream) -> syn::Result<Self> {
todo!()
}
}
type ColumnList = syn::punctuated::Punctuated<syn::Ident, syn::Token![,]>;
struct Select {
select_token: kw::SELECT,
column_list: Option<ColumnList>,
from_token: kw::FROM,
what: syn::TypePath,
where_token: Option<kw::WHERE>,
where_clause: Option<Expr>
}
impl Parse for Select {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let mut where_token = None;
Ok(Self {
select_token: input.parse()?,
column_list: {
if input.peek(kw::FROM) {
None
}
else {
Some(ColumnList::parse_separated_nonempty(input)?)
}
},
from_token: input.parse()?,
what: input.parse()?,
where_token: {
where_token = input.parse()?;
where_token
},
where_clause: {
if where_token.is_some() {
Some(input.parse()?)
}
else {
None
}
}
})
}
}
pub fn do_query(tokens: TokenStream) -> TokenStream {
let input = parse_macro_input!(tokens as Select);
quote!{
}.into()
}