use crate::prelude::*;
use proc_macro2::Span;
pub struct DefaultExpr {
is_string: bool,
expr: String,
}
impl ToTokens for DefaultExpr {
fn to_tokens(&self, tokens: &mut TokenStream2) {
if !self.is_string {
let expr = &self.expr;
tokens.extend(quote!(#expr));
} else {
let expr = &self.expr; let snippet = format!("'{}'", expr);
let ts = snippet.parse::<TokenStream2>().expect("Invalid SQL string snippet");
tokens.extend(ts);
}
}
}
impl Parse for DefaultExpr {
fn parse(input: parse::ParseStream) -> Result<Self> {
use sql_from_models_parser::{dialect::*, parser::Parser, tokenizer::*};
let span = Span::call_site();
let mut is_string = false;
let expr = match input.parse::<Lit>() {
Ok(Lit::Bool(boolean)) => boolean.value().to_string(),
Ok(Lit::Int(int)) => int.to_string(),
Ok(Lit::Float(float)) => float.to_string(),
Ok(Lit::Str(string)) => {
is_string = true;
string.value()
}
Ok(lit) => {
return Err(Error::new(
lit.span(),
"Expected string, boolean, or numeric literal",
));
}
Err(err) => {
return Err(Error::new(
err.span(),
"Expected string, boolean, or numeric literal",
));
}
};
let mut lexer = Tokenizer::new(&GenericDialect {}, &expr);
let tokens = lexer.tokenize().map_err(|err| {
syn::Error::new(span, format!("Failed to tokenize default expression: {:?}", err))
})?;
Parser::new(tokens, &GenericDialect {})
.parse_expr()
.map_err(|err| {
syn::Error::new(span, format!("Failed to parse default expression: {}", err))
})?;
Ok(DefaultExpr { is_string, expr })
}
}