use crate::db::query::{
builder::{
AggregateExpr, FieldRef, NumericProjectionExpr, RoundProjectionExpr, TextProjectionExpr,
},
plan::{
OrderDirection, OrderTerm as PlannedOrderTerm,
expr::{Expr, FieldId},
},
};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct OrderExpr {
expr: Expr,
}
impl OrderExpr {
#[must_use]
pub fn field(field: impl Into<String>) -> Self {
let field = field.into();
Self {
expr: Expr::Field(FieldId::new(field)),
}
}
const fn new(expr: Expr) -> Self {
Self { expr }
}
pub(in crate::db) fn lower(&self, direction: OrderDirection) -> PlannedOrderTerm {
PlannedOrderTerm::new(self.expr.clone(), direction)
}
}
impl From<&str> for OrderExpr {
fn from(value: &str) -> Self {
Self::field(value)
}
}
impl From<String> for OrderExpr {
fn from(value: String) -> Self {
Self::field(value)
}
}
impl From<FieldRef> for OrderExpr {
fn from(value: FieldRef) -> Self {
Self::field(value.as_str())
}
}
impl From<TextProjectionExpr> for OrderExpr {
fn from(value: TextProjectionExpr) -> Self {
Self::new(value.expr().clone())
}
}
impl From<NumericProjectionExpr> for OrderExpr {
fn from(value: NumericProjectionExpr) -> Self {
Self::new(value.expr().clone())
}
}
impl From<RoundProjectionExpr> for OrderExpr {
fn from(value: RoundProjectionExpr) -> Self {
Self::new(value.expr().clone())
}
}
impl From<AggregateExpr> for OrderExpr {
fn from(value: AggregateExpr) -> Self {
Self::new(Expr::Aggregate(value))
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct OrderTerm {
expr: OrderExpr,
direction: OrderDirection,
}
impl OrderTerm {
#[must_use]
pub fn asc(expr: impl Into<OrderExpr>) -> Self {
Self {
expr: expr.into(),
direction: OrderDirection::Asc,
}
}
#[must_use]
pub fn desc(expr: impl Into<OrderExpr>) -> Self {
Self {
expr: expr.into(),
direction: OrderDirection::Desc,
}
}
pub(in crate::db) fn lower(&self) -> PlannedOrderTerm {
self.expr.lower(self.direction)
}
}
#[must_use]
pub fn field(field: impl Into<String>) -> OrderExpr {
OrderExpr::field(field)
}
#[must_use]
pub fn asc(expr: impl Into<OrderExpr>) -> OrderTerm {
OrderTerm::asc(expr)
}
#[must_use]
pub fn desc(expr: impl Into<OrderExpr>) -> OrderTerm {
OrderTerm::desc(expr)
}