use crate::ast::{Column, Expression};
pub type OrderDefinition<'a> = (Expression<'a>, Option<Order>);
#[derive(Debug, Default, PartialEq, Clone)]
pub struct Ordering<'a>(pub Vec<OrderDefinition<'a>>);
impl<'a> Ordering<'a> {
#[doc(hidden)]
pub fn append(mut self, value: OrderDefinition<'a>) -> Self {
self.0.push(value);
self
}
pub fn new(values: Vec<OrderDefinition<'a>>) -> Self {
Self(values)
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Order {
Asc,
Desc,
AscNullsFirst,
AscNullsLast,
DescNullsFirst,
DescNullsLast,
}
pub trait Orderable<'a>
where
Self: Sized,
{
fn order(self, order: Option<Order>) -> OrderDefinition<'a>;
fn ascend(self) -> OrderDefinition<'a> {
self.order(Some(Order::Asc))
}
fn descend(self) -> OrderDefinition<'a> {
self.order(Some(Order::Desc))
}
fn ascend_nulls_first(self) -> OrderDefinition<'a> {
self.order(Some(Order::AscNullsFirst))
}
fn ascend_nulls_last(self) -> OrderDefinition<'a> {
self.order(Some(Order::AscNullsLast))
}
fn descend_nulls_first(self) -> OrderDefinition<'a> {
self.order(Some(Order::DescNullsFirst))
}
fn descend_nulls_last(self) -> OrderDefinition<'a> {
self.order(Some(Order::DescNullsLast))
}
}
pub trait IntoOrderDefinition<'a> {
fn into_order_definition(self) -> OrderDefinition<'a>;
}
impl<'a> IntoOrderDefinition<'a> for &'a str {
fn into_order_definition(self) -> OrderDefinition<'a> {
let column: Column<'a> = self.into();
(column.into(), None)
}
}
impl<'a> IntoOrderDefinition<'a> for Column<'a> {
fn into_order_definition(self) -> OrderDefinition<'a> {
(self.into(), None)
}
}
impl<'a> IntoOrderDefinition<'a> for OrderDefinition<'a> {
fn into_order_definition(self) -> OrderDefinition<'a> {
self
}
}
impl<'a> Orderable<'a> for Column<'a> {
fn order(self, order: Option<Order>) -> OrderDefinition<'a> {
(self.into(), order)
}
}
impl<'a> Orderable<'a> for &'a str {
fn order(self, order: Option<Order>) -> OrderDefinition<'a> {
let column: Column<'a> = self.into();
column.order(order)
}
}
impl<'a> Orderable<'a> for (&'a str, &'a str) {
fn order(self, order: Option<Order>) -> OrderDefinition<'a> {
let column: Column<'a> = self.into();
column.order(order)
}
}