use crate::expr::Expr;
use crate::expr::write_expr;
use crate::types::IntoColumnRef;
use crate::writer::SqlWriter;
#[derive(Debug, Clone, PartialEq)]
pub struct Order {
expr: Expr,
direction: SortDirection,
nulls: Option<NullOrdering>,
}
#[derive(Debug, Clone, PartialEq)]
enum SortDirection {
Asc,
Desc,
}
#[derive(Debug, Clone, PartialEq)]
enum NullOrdering {
First,
Last,
}
impl Order {
pub fn column<T>(col: T) -> Self
where
T: IntoColumnRef,
{
Self {
expr: Expr::column(col),
direction: SortDirection::Asc,
nulls: None,
}
}
pub fn expr<E>(expr: E) -> Self
where
E: Into<Expr>,
{
Self {
expr: expr.into(),
direction: SortDirection::Asc,
nulls: None,
}
}
pub fn asc(mut self) -> Self {
self.direction = SortDirection::Asc;
self
}
pub fn desc(mut self) -> Self {
self.direction = SortDirection::Desc;
self
}
pub fn nulls_first(mut self) -> Self {
self.nulls = Some(NullOrdering::First);
self
}
pub fn nulls_last(mut self) -> Self {
self.nulls = Some(NullOrdering::Last);
self
}
}
pub(crate) fn write_order<W: SqlWriter>(w: &mut W, order: &Order) {
write_expr(w, &order.expr);
match order.direction {
SortDirection::Asc => w.push_str(" ASC"),
SortDirection::Desc => w.push_str(" DESC"),
}
if let Some(nulls) = &order.nulls {
match nulls {
NullOrdering::First => w.push_str(" NULLS FIRST"),
NullOrdering::Last => w.push_str(" NULLS LAST"),
}
}
}