use proc_macro2::TokenStream;
use quote::{ToTokens, quote};
use syn::{
Ident, Token,
parse::{Parse, ParseStream},
spanned::Spanned,
};
use crate::{
clause::peek_clause,
keyword,
parse_option::ParseOption,
part::ColumnList,
pretty::{PrettyPrint, Printer},
quote_option::QuoteOption,
};
pub struct TableAlias {
pub as_token: Option<Token![as]>,
pub name: Ident,
pub columns: Option<ColumnList>,
}
impl ParseOption for TableAlias {
fn peek(_input: ParseStream) -> bool {
true
}
fn parse_option(input: ParseStream) -> syn::Result<Option<Self>> {
if input.is_empty() || peek_clause(input) {
return Ok(None);
}
macro_rules! check {
($kw:expr) => {
if input.peek($kw) {
return Ok(None);
}
};
}
check!(keyword::inner);
check!(keyword::left);
check!(keyword::right);
check!(keyword::full);
check!(keyword::on);
check!(keyword::natural);
check!(keyword::cross);
Ok(Some(input.parse()?))
}
}
impl Parse for TableAlias {
fn parse(input: ParseStream) -> syn::Result<Self> {
Ok(Self {
as_token: input.peek(Token![as]).then(|| input.parse()).transpose()?,
name: input.parse()?,
columns: {
let columns = input
.peek(syn::token::Paren)
.then(|| input.parse::<ColumnList>())
.transpose()?;
if let Some(columns) = columns {
return Err(syn::Error::new(
columns.paren_token.span.span(),
"column aliases are currently unsupported",
));
}
columns
},
})
}
}
impl ToTokens for TableAlias {
fn to_tokens(&self, tokens: &mut TokenStream) {
let name = &self.name.to_string();
let columns = QuoteOption::from(&self.columns);
quote! {
::kosame::repr::part::TableAlias::new(#name, #columns)
}
.to_tokens(tokens);
}
}
impl PrettyPrint for TableAlias {
fn pretty_print(&self, printer: &mut Printer<'_>) {
" ".pretty_print(printer);
self.as_token.pretty_print(printer);
" ".pretty_print(printer);
self.name.pretty_print(printer);
self.columns.pretty_print(printer);
}
}