grafbase_sql_ast/ast/
ordering.rs

1use crate::ast::{Column, Expression};
2
3/// Defines ordering for an `ORDER BY` statement.
4pub type OrderDefinition<'a> = (Expression<'a>, Option<Order>);
5
6/// A list of definitions for the `ORDER BY` statement.
7#[derive(Debug, Default, PartialEq, Clone)]
8pub struct Ordering<'a>(pub Vec<OrderDefinition<'a>>);
9
10impl<'a> Ordering<'a> {
11    pub fn append(&mut self, value: OrderDefinition<'a>) {
12        self.0.push(value);
13    }
14
15    pub fn new(values: Vec<OrderDefinition<'a>>) -> Self {
16        Self(values)
17    }
18
19    pub fn is_empty(&self) -> bool {
20        self.0.is_empty()
21    }
22}
23
24/// The ordering direction
25#[derive(Clone, Copy, Debug, Eq, PartialEq)]
26pub enum Order {
27    /// Ascending
28    Asc,
29    /// Descending
30    Desc,
31    /// Ascending Nulls First
32    AscNullsFirst,
33    /// Ascending Nulls Last
34    AscNullsLast,
35    /// Descending Nulls First
36    DescNullsFirst,
37    /// Descending Nulls Last
38    DescNullsLast,
39}
40
41/// An item that can be used in the `ORDER BY` statement
42pub trait Orderable<'a>
43where
44    Self: Sized,
45{
46    /// Order by `self` in the given order
47    fn order(self, order: Option<Order>) -> OrderDefinition<'a>;
48
49    /// Change the order to `ASC`
50    fn ascend(self) -> OrderDefinition<'a> {
51        self.order(Some(Order::Asc))
52    }
53
54    /// Change the order to `DESC`
55    fn descend(self) -> OrderDefinition<'a> {
56        self.order(Some(Order::Desc))
57    }
58
59    /// Change the order to `ASC NULLS FIRST`
60    fn ascend_nulls_first(self) -> OrderDefinition<'a> {
61        self.order(Some(Order::AscNullsFirst))
62    }
63
64    /// Change the order to `ASC NULLS LAST`
65    fn ascend_nulls_last(self) -> OrderDefinition<'a> {
66        self.order(Some(Order::AscNullsLast))
67    }
68
69    /// Change the order to `DESC NULLS FIRST`
70    fn descend_nulls_first(self) -> OrderDefinition<'a> {
71        self.order(Some(Order::DescNullsFirst))
72    }
73
74    /// Change the order to `ASC NULLS LAST`
75    fn descend_nulls_last(self) -> OrderDefinition<'a> {
76        self.order(Some(Order::DescNullsLast))
77    }
78}
79
80/// Convert the value into an order definition with order item and direction
81pub trait IntoOrderDefinition<'a> {
82    fn into_order_definition(self) -> OrderDefinition<'a>;
83}
84
85impl<'a> IntoOrderDefinition<'a> for &'a str {
86    fn into_order_definition(self) -> OrderDefinition<'a> {
87        let column: Column<'a> = self.into();
88        (column.into(), None)
89    }
90}
91
92impl<'a> IntoOrderDefinition<'a> for Column<'a> {
93    fn into_order_definition(self) -> OrderDefinition<'a> {
94        (self.into(), None)
95    }
96}
97
98impl<'a> IntoOrderDefinition<'a> for OrderDefinition<'a> {
99    fn into_order_definition(self) -> OrderDefinition<'a> {
100        self
101    }
102}
103
104impl<'a> Orderable<'a> for Column<'a> {
105    fn order(self, order: Option<Order>) -> OrderDefinition<'a> {
106        (self.into(), order)
107    }
108}
109
110impl<'a> Orderable<'a> for &'a str {
111    fn order(self, order: Option<Order>) -> OrderDefinition<'a> {
112        let column: Column<'a> = self.into();
113        column.order(order)
114    }
115}
116
117impl<'a> Orderable<'a> for (&'a str, &'a str) {
118    fn order(self, order: Option<Order>) -> OrderDefinition<'a> {
119        let column: Column<'a> = self.into();
120        column.order(order)
121    }
122}