grafbase_sql_ast/ast/
grouping.rs

1use super::Function;
2use crate::ast::{Column, Expression, Table};
3
4/// Defines a grouping for the `GROUP BY` statement.
5pub type GroupByDefinition<'a> = Expression<'a>;
6
7/// A list of definitions for the `GROUP BY` statement
8#[derive(Debug, Default, PartialEq, Clone)]
9pub struct Grouping<'a>(pub Vec<GroupByDefinition<'a>>);
10
11impl<'a> Grouping<'a> {
12    #[doc(hidden)]
13    pub fn append(&mut self, value: GroupByDefinition<'a>) {
14        self.0.push(value);
15    }
16
17    pub fn new(values: Vec<GroupByDefinition<'a>>) -> Self {
18        Self(values)
19    }
20
21    pub fn is_empty(&self) -> bool {
22        self.0.is_empty()
23    }
24}
25
26/// An item that can be used in the `GROUP BY` statement
27pub trait Groupable<'a>
28where
29    Self: Sized,
30{
31    /// Group by `self`
32    fn group(self) -> GroupByDefinition<'a>;
33}
34
35/// Convert the value into a group by definition.
36pub trait IntoGroupByDefinition<'a> {
37    fn into_group_by_definition(self) -> GroupByDefinition<'a>;
38}
39
40impl<'a> IntoGroupByDefinition<'a> for &'a str {
41    fn into_group_by_definition(self) -> GroupByDefinition<'a> {
42        let column: Column = self.into();
43        column.into()
44    }
45}
46
47impl<'a> IntoGroupByDefinition<'a> for (&'a str, &'a str) {
48    fn into_group_by_definition(self) -> GroupByDefinition<'a> {
49        let column: Column = self.into();
50        column.into()
51    }
52}
53
54impl<'a> IntoGroupByDefinition<'a> for (&'a str, &'a str, &'a str) {
55    fn into_group_by_definition(self) -> GroupByDefinition<'a> {
56        let table: Table = self.1.into();
57        let column: Column = self.2.into();
58
59        column.table(table.database(self.0)).into()
60    }
61}
62
63impl<'a> IntoGroupByDefinition<'a> for Column<'a> {
64    fn into_group_by_definition(self) -> GroupByDefinition<'a> {
65        self.into()
66    }
67}
68
69impl<'a> IntoGroupByDefinition<'a> for Function<'a> {
70    fn into_group_by_definition(self) -> GroupByDefinition<'a> {
71        self.into()
72    }
73}
74
75impl<'a> IntoGroupByDefinition<'a> for GroupByDefinition<'a> {
76    fn into_group_by_definition(self) -> GroupByDefinition<'a> {
77        self
78    }
79}
80
81impl<'a> Groupable<'a> for Column<'a> {
82    fn group(self) -> GroupByDefinition<'a> {
83        self.into()
84    }
85}
86
87impl<'a> Groupable<'a> for &'a str {
88    fn group(self) -> GroupByDefinition<'a> {
89        Column::from(self).group()
90    }
91}