use std::rc::Rc;
use antlr_rust::token::Token;
use antlr_rust::tree::ParseTree;
use hamelin_lib::antlr::hamelinparser::StringContextAll;
use hamelin_lib::err::{TranslationError, TranslationErrors};
use hamelin_lib::sql::expression::literal::{StringLiteral, UnicodeStringLiteral};
use hamelin_lib::sql::expression::SQLExpression;
pub struct HamelinStringLiteral {
pub ctx: Rc<StringContextAll<'static>>,
}
impl HamelinStringLiteral {
pub fn new(ctx: Rc<StringContextAll<'static>>) -> Self {
Self { ctx }
}
pub fn translate(&self) -> Result<SQLExpression, TranslationErrors> {
fn literal_text(text: &str, quote: &str) -> String {
let double_quote = quote.to_string() + quote;
text[1..text.len() - 1].replace(&double_quote, "e)
}
fn unicode_literal(value: &str, uesc: Option<&str>, quote: &str) -> UnicodeStringLiteral {
let value = literal_text(&value[2..], quote);
let uesc = uesc.map(|u| literal_text(u, "'"));
UnicodeStringLiteral::new(&value, uesc)
}
let exp: SQLExpression = match self.ctx.as_ref() {
StringContextAll::BasicSingleQuotedStringLiteralContext(ctx) => {
StringLiteral::new(&literal_text(&ctx.get_text(), "'")).into()
}
StringContextAll::BasicDoubleQuotedStringLiteralContext(ctx) => {
StringLiteral::new(&literal_text(&ctx.get_text(), "\"")).into()
}
StringContextAll::UnicodeSingleQuotedStringLiteralContext(ctx) => {
let value_text = ctx.value.as_ref().unwrap().get_text();
let uesc_text = ctx.uesc.as_ref().map(|u| u.get_text());
unicode_literal(value_text, uesc_text, "'").into()
}
StringContextAll::UnicodeDoubleQuotedStringLiteralContext(ctx) => {
let value_text = ctx.value.as_ref().unwrap().get_text();
let uesc_text = ctx.uesc.as_ref().map(|u| u.get_text());
unicode_literal(value_text, uesc_text, "\"").into()
}
StringContextAll::Error(ctx) => {
return TranslationError::msg(ctx, "parse error").single_result();
}
};
Ok(exp)
}
}