#[cfg(feature = "try-parse")]
use proc_macro_error2::emit_error;
use proc_macro2::{Ident, TokenStream as TokenStream2};
use quote::{ToTokens, quote};
use syn::parse::{Parse, ParseStream};
#[cfg(feature = "try-parse")]
use syn::parse_quote_spanned;
use syn::{LitStr, Token, Type};
#[cfg_attr(debug_assertions, derive(Debug))]
pub(crate) enum Columns {
All,
Defined(Vec<(String, String)>),
}
impl ToTokens for Columns {
fn to_tokens(&self, tokens: &mut TokenStream2) {
let expanded = match self {
Columns::All => quote! {"*"},
Columns::Defined(cols) => {
let columns = cols
.iter()
.map(|(name, alias)| quote! {#name as #alias}.to_string())
.collect::<Vec<_>>()
.join(",");
quote! {#columns}
}
};
tokens.extend(expanded);
}
}
impl Parse for Columns {
fn parse(input: ParseStream) -> syn::Result<Self> {
if input.peek(Token![*]) {
input.parse::<Token![*]>()?;
Ok(Columns::All)
} else {
let mut columns = Vec::new();
while !input.is_empty() {
let name: Ident = input.parse()?;
let alias = if input.peek(Token![as]) {
input.parse::<Token![as]>()?;
let alias: Ident = input.parse()?;
alias.to_string()
} else {
name.to_string()
};
columns.push((name.to_string(), alias));
if !input.peek(Token![,]) {
break;
}
input.parse::<Token![,]>()?;
}
Ok(Columns::Defined(columns))
}
}
}
#[cfg_attr(feature = "debug", derive(Debug))]
pub(crate) enum ColumnVal {
Type(Box<Type>),
Raw(LitStr),
}
impl Parse for ColumnVal {
fn parse(input: ParseStream) -> syn::Result<Self> {
let lookahead = input.lookahead1();
if lookahead.peek(LitStr) {
Ok(Self::Raw(input.parse()?))
} else {
Ok(Self::Type(input.parse().unwrap_or_else(|err| {
let span = err.span();
#[cfg(not(feature = "try-parse"))]
proc_macro_error2::abort!(
span, "Expected column value to be either a literal string or a Type";
help = "See https://docs.rs/syn/2.0.99/syn/enum.Type.html for supported types."
);
#[cfg(feature = "try-parse")]
emit_error!(
span, "Expected column value to be either a literal string or a Type";
help = "See https://docs.rs/syn/2.0.99/syn/enum.Type.html for supported types."
);
#[cfg(feature = "try-parse")]
parse_quote_spanned! { span=> ()}
})))
}
}
}