use crate::Expr;
use crate::surreal_expr;
use vantage_expressions::{Expressive, ExpressiveOr};
use vantage_table::column::core::{Column, ColumnType};
#[derive(Debug, Clone)]
pub struct Identifier {
identifier: String,
}
impl Identifier {
pub fn new(identifier: impl Into<String>) -> Self {
Self {
identifier: identifier.into(),
}
}
pub fn dot(self, other: impl Into<String>) -> crate::Expr {
surreal_expr!("{}.{}", (self), (Identifier::new(other.into())))
}
fn needs_escaping(&self) -> bool {
let reserved_keywords = [
"DEFINE", "CREATE", "SELECT", "UPDATE", "DELETE", "FROM", "RETURN", "WHERE", "SET",
"ONLY", "TABLE",
];
let upper_identifier = self.identifier.to_uppercase();
self.identifier.contains(' ') || reserved_keywords.contains(&upper_identifier.as_str())
}
}
impl From<Identifier> for crate::Expr {
fn from(val: Identifier) -> Self {
val.expr()
}
}
impl Expressive<crate::AnySurrealType> for Identifier {
fn expr(&self) -> crate::Expr {
use vantage_expressions::Expression;
if self.needs_escaping() {
Expression::new(format!("⟨{}⟩", self.identifier), vec![])
} else {
Expression::new(self.identifier.clone(), vec![])
}
}
}
pub struct Parent {}
impl Parent {
pub fn identifier() -> Identifier {
Identifier::new("$parent")
}
}
impl ExpressiveOr<crate::AnySurrealType, Identifier> for &str {
fn field_expr(&self) -> Expr {
Identifier::new(*self).expr()
}
}
impl ExpressiveOr<crate::AnySurrealType, Identifier> for String {
fn field_expr(&self) -> Expr {
Identifier::new(self.as_str()).expr()
}
}
impl ExpressiveOr<crate::AnySurrealType, Identifier> for Identifier {
fn field_expr(&self) -> Expr {
Expressive::expr(self)
}
}
impl ExpressiveOr<crate::AnySurrealType, Identifier> for Expr {
fn field_expr(&self) -> Expr {
self.clone()
}
}
impl ExpressiveOr<crate::AnySurrealType, Identifier> for crate::field::Field {
fn field_expr(&self) -> Expr {
Expressive::expr(self)
}
}
impl<T: ColumnType> ExpressiveOr<crate::AnySurrealType, Identifier> for Column<T> {
fn field_expr(&self) -> Expr {
Identifier::new(self.name()).expr()
}
}