edgedb_query/queries/
select.rs1
2const ORDER_BY: &str = "order by";
3const LIMIT: &str = "limit";
4const OFFSET: &str = "offset";
5const ASC: &str = " asc";
6const DESC: &str = " desc";
7
8pub trait Options {
13
14 fn order_options(&self) -> Option<OrderOptions>;
16
17 fn page_options(&self) -> Option<PageOptions>;
19}
20
21pub fn parse_options<T: Options>(options: &T, table_name: impl Into<String>, result_fields: Vec<&str>) -> String {
46
47 let mut stmt = String::default();
48
49 let table_name = table_name.into();
50
51 if let Some(OrderOptions {
52 order_by,
53 order_direction,
54 }) = options.order_options().clone()
55 {
56 if !result_fields.contains(&order_by.as_str()) {
57 panic!("'order by' value must be one of {:#?}", result_fields)
58 }
59
60 stmt.push_str(format!(" {} {}.{}", ORDER_BY, table_name, order_by).as_str());
61
62 if let Some(OrderDir::Desc) = order_direction {
63 stmt.push_str(DESC)
64 } else {
65 stmt.push_str(ASC)
66 }
67 }
68
69 if let Some(PageOptions { limit, offset }) = options.page_options().clone() {
70 stmt.push_str(format!(" {} {}", LIMIT, limit).as_str());
71
72 if let Some(off) = offset {
73 stmt.push_str(format!(" {} {}", OFFSET, off).as_str());
74 }
75 }
76
77 stmt
78}
79
80#[derive(Debug, Clone)]
82pub enum OrderDir {
83 Asc,
84 Desc,
85}
86
87#[derive(Debug, Clone)]
89pub struct OrderOptions {
90 pub order_by: String,
91 pub order_direction: Option<OrderDir>,
92}
93
94#[derive(Debug, Clone)]
96pub struct PageOptions {
97 pub limit: u32,
98 pub offset: Option<u32>,
99}
100
101#[derive(Debug, Clone)]
103pub struct SelectOptions {
104 pub order_options: Option<OrderOptions>,
105 pub page_options: Option<PageOptions>,
106}
107
108impl Options for SelectOptions {
109
110 fn order_options(&self) -> Option<OrderOptions> {
111 self.order_options.clone()
112 }
113
114 fn page_options(&self) -> Option<PageOptions> {
115 self.page_options.clone()
116 }
117}