use crate::err::Context;
use crate::tree::ast::expression::{
Cast, Expression, FieldReference, TruncUnit, TsTrunc, TsTruncUnit,
};
use crate::tree::ast::identifier::SimpleIdentifier;
use crate::tree::ast::node::Span;
use crate::tree::builder::{ExpressionBuilder, IntoExpressionBuilder};
use crate::types::Type;
use std::sync::Arc;
#[derive(Debug)]
pub struct CastBuilder {
expression: Box<dyn ExpressionBuilder>,
target_type: Type,
}
impl CastBuilder {
pub fn new(expression: impl IntoExpressionBuilder, target_type: Type) -> Self {
Self {
expression: expression.into_expression_builder(),
target_type,
}
}
}
impl ExpressionBuilder for CastBuilder {
fn build(&self) -> Expression {
Expression {
span: Span::NONE,
kind: Cast {
expression: Arc::new(self.expression.build()),
target_type: Arc::new(self.target_type.clone()),
}
.into(),
}
}
}
impl IntoExpressionBuilder for CastBuilder {
fn into_expression_builder(self) -> Box<dyn ExpressionBuilder> {
Box::new(self)
}
}
#[derive(Debug)]
pub struct TsTruncBuilder {
expression: Box<dyn ExpressionBuilder>,
unit: TruncUnit,
multiplier: u32,
}
impl TsTruncBuilder {
pub fn new(expression: impl IntoExpressionBuilder, unit: TruncUnit) -> Self {
Self {
expression: expression.into_expression_builder(),
unit,
multiplier: 1,
}
}
pub fn with_multiplier(
expression: impl IntoExpressionBuilder,
unit: TruncUnit,
multiplier: u32,
) -> Self {
Self {
expression: expression.into_expression_builder(),
unit,
multiplier,
}
}
pub fn to_second(expression: impl IntoExpressionBuilder) -> Self {
Self::new(expression, TruncUnit::Second)
}
pub fn to_minute(expression: impl IntoExpressionBuilder) -> Self {
Self::new(expression, TruncUnit::Minute)
}
pub fn to_hour(expression: impl IntoExpressionBuilder) -> Self {
Self::new(expression, TruncUnit::Hour)
}
pub fn to_day(expression: impl IntoExpressionBuilder) -> Self {
Self::new(expression, TruncUnit::Day)
}
pub fn to_week(expression: impl IntoExpressionBuilder) -> Self {
Self::new(expression, TruncUnit::Week)
}
pub fn to_month(expression: impl IntoExpressionBuilder) -> Self {
Self::new(expression, TruncUnit::Month)
}
pub fn to_year(expression: impl IntoExpressionBuilder) -> Self {
Self::new(expression, TruncUnit::Year)
}
}
impl ExpressionBuilder for TsTruncBuilder {
fn build(&self) -> Expression {
Expression {
span: Span::NONE,
kind: TsTrunc {
expression: Arc::new(self.expression.build()),
unit: TsTruncUnit::fixed(self.unit, self.multiplier),
}
.into(),
}
}
}
impl IntoExpressionBuilder for TsTruncBuilder {
fn into_expression_builder(self) -> Box<dyn ExpressionBuilder> {
Box::new(self)
}
}
#[derive(Debug)]
pub struct FieldReferenceBuilder {
field_name: SimpleIdentifier,
}
impl FieldReferenceBuilder {
pub fn new(name: impl Into<SimpleIdentifier>) -> Self {
Self {
field_name: name.into(),
}
}
}
impl ExpressionBuilder for FieldReferenceBuilder {
fn build(&self) -> Expression {
Expression {
span: Span::NONE,
kind: FieldReference {
field_name: self.field_name.clone().into(),
}
.into(),
}
}
}
impl IntoExpressionBuilder for FieldReferenceBuilder {
fn into_expression_builder(self) -> Box<dyn ExpressionBuilder> {
Box::new(self)
}
}
pub fn field_ref(name: impl Into<SimpleIdentifier>) -> FieldReferenceBuilder {
FieldReferenceBuilder::new(name)
}
#[derive(Debug)]
pub struct ErrorBuilder {
message: String,
}
impl ErrorBuilder {
pub fn new(message: impl Into<String>) -> Self {
Self {
message: message.into(),
}
}
}
impl ExpressionBuilder for ErrorBuilder {
fn build(&self) -> Expression {
use crate::err::TranslationError;
use crate::tree::ast::expression::ErrorExpression;
Expression {
span: Span::NONE,
kind: ErrorExpression {
error: Arc::new(TranslationError::new(Context::new(0..=0, &self.message))),
}
.into(),
}
}
}
impl IntoExpressionBuilder for ErrorBuilder {
fn into_expression_builder(self) -> Box<dyn ExpressionBuilder> {
Box::new(self)
}
}
pub fn cast(expression: impl IntoExpressionBuilder, target_type: Type) -> CastBuilder {
CastBuilder::new(expression, target_type)
}
pub fn at(expression: impl IntoExpressionBuilder, unit: TruncUnit) -> TsTruncBuilder {
TsTruncBuilder::new(expression, unit)
}
pub fn at_second(expression: impl IntoExpressionBuilder) -> TsTruncBuilder {
TsTruncBuilder::to_second(expression)
}
pub fn at_minute(expression: impl IntoExpressionBuilder) -> TsTruncBuilder {
TsTruncBuilder::to_minute(expression)
}
pub fn at_hour(expression: impl IntoExpressionBuilder) -> TsTruncBuilder {
TsTruncBuilder::to_hour(expression)
}
pub fn at_day(expression: impl IntoExpressionBuilder) -> TsTruncBuilder {
TsTruncBuilder::to_day(expression)
}
pub fn at_week(expression: impl IntoExpressionBuilder) -> TsTruncBuilder {
TsTruncBuilder::to_week(expression)
}
pub fn at_month(expression: impl IntoExpressionBuilder) -> TsTruncBuilder {
TsTruncBuilder::to_month(expression)
}
pub fn at_year(expression: impl IntoExpressionBuilder) -> TsTruncBuilder {
TsTruncBuilder::to_year(expression)
}
pub fn error(message: impl Into<String>) -> ErrorBuilder {
ErrorBuilder::new(message)
}