1use derive_builder::Builder;
2use serde::Serialize;
3use serde_with::skip_serializing_none;
4
5#[skip_serializing_none]
6#[derive(Serialize, Debug, Eq, PartialEq, Clone, Default, Builder)]
7#[builder(setter(strip_option))]
8#[builder(default)]
9pub struct QueryDatabaseRequest {
10 pub filter: Option<Filter>,
11 pub sorts: Option<Vec<Sort>>,
12 pub start_cursor: Option<String>,
13 pub page_size: Option<u32>,
14}
15
16#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
17#[serde(untagged, rename_all = "snake_case")]
18pub enum Filter {
19 Value {
20 #[serde(flatten)]
21 filter_type: FilterType,
22 },
23 And {
24 and: Vec<FilterType>,
25 },
26 Or {
27 or: Vec<FilterType>,
28 },
29}
30
31#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
32#[serde(untagged, rename_all = "snake_case")]
33pub enum FilterType {
34 Property {
35 property: String,
36 #[serde(flatten)]
37 condition: PropertyCondition,
38 },
39 Timestamp {
40 timestamp: Timestamp,
41 #[serde(flatten)]
42 condition: TimestampCondition,
43 },
44}
45
46#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
47#[serde(rename_all = "snake_case")]
48pub enum Timestamp {
49 CreatedTime,
50 LastEditedTime,
51}
52
53#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
54#[serde(untagged, rename_all = "snake_case")]
55pub enum Sort {
56 Property {
57 property: String,
58 direction: SortDirection,
59 },
60 Timestamp {
61 timestamp: Timestamp,
62 direction: SortDirection,
63 },
64}
65
66#[derive(Serialize, Debug, Eq, PartialEq, Hash, Clone)]
67#[serde(rename_all = "snake_case")]
68pub enum SortDirection {
69 Ascending,
70 Descending,
71}
72
73use chrono::{DateTime, Utc};
74use serde::{ser::SerializeMap, Serializer};
75use serde_json::Number;
76
77fn serialize_to_true<S>(serializer: S) -> Result<S::Ok, S::Error>
78where
79 S: Serializer,
80{
81 serializer.serialize_bool(true)
82}
83
84fn serialize_to_empty_object<S>(serializer: S) -> Result<S::Ok, S::Error>
85where
86 S: Serializer,
87{
88 serializer.serialize_map(Some(0))?.end()
89}
90
91#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
92#[serde(rename_all = "snake_case")]
93pub enum PropertyCondition {
94 Checkbox(CheckBoxCondition),
95 Date(DateCondition),
96 Files(FilesCondition),
97 Formula(FormulaCondition),
98 MultiSelect(MultiSelectCondition),
99 Number(NumberCondition),
100 People(PeopleCondition),
101 Relation(RelationCondition),
102 RichText(RichTextCondition),
103 Rollup(Box<RollupCondition>),
104 Select(SelectCondition),
105 Status(StatusCondition),
106 Timestamp(TimestampCondition),
107 ID(IDCondition),
108}
109
110#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
111#[serde(rename_all = "snake_case")]
112pub enum CheckBoxCondition {
113 Equals(bool),
114 DoesNotEqual(bool),
115}
116
117#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
118#[serde(rename_all = "snake_case")]
119pub enum DateCondition {
120 After(DateTime<Utc>),
121 Before(DateTime<Utc>),
122 Equals(DateTime<Utc>),
123 #[serde(serialize_with = "serialize_to_true")]
124 IsEmpty,
125 #[serde(serialize_with = "serialize_to_true")]
126 IsNotEmpty,
127 #[serde(serialize_with = "serialize_to_empty_object")]
128 NextMonth,
129 #[serde(serialize_with = "serialize_to_empty_object")]
130 NextWeek,
131 #[serde(serialize_with = "serialize_to_empty_object")]
132 NextYear,
133 OnOrAfter(DateTime<Utc>),
134 OnOrBefore(DateTime<Utc>),
135 #[serde(serialize_with = "serialize_to_empty_object")]
136 PastMonth,
137 #[serde(serialize_with = "serialize_to_empty_object")]
138 PastWeek,
139 #[serde(serialize_with = "serialize_to_empty_object")]
140 PastYear,
141 #[serde(serialize_with = "serialize_to_empty_object")]
142 ThisWeek,
143}
144
145#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
146#[serde(rename_all = "snake_case")]
147pub enum FilesCondition {
148 #[serde(serialize_with = "serialize_to_true")]
149 IsEmpty,
150 #[serde(serialize_with = "serialize_to_true")]
151 IsNotEmpty,
152}
153
154#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
155#[serde(rename_all = "snake_case")]
156pub enum FormulaCondition {
157 Checkbox(CheckBoxCondition),
158 Date(DateCondition),
159 Number(NumberCondition),
160 String(RichTextCondition),
161}
162
163#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
164#[serde(rename_all = "snake_case")]
165pub enum MultiSelectCondition {
166 Contains(String),
167 DoesNotContain(String),
168 #[serde(serialize_with = "serialize_to_true")]
169 IsEmpty,
170 #[serde(serialize_with = "serialize_to_true")]
171 IsNotEmpty,
172}
173
174#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
175#[serde(rename_all = "snake_case")]
176pub enum NumberCondition {
177 DoesNotEqual(Number),
178 Equals(Number),
179 GreaterThan(Number),
180 GreaterThanOrEqualTo(Number),
181 #[serde(serialize_with = "serialize_to_true")]
182 IsEmpty,
183 #[serde(serialize_with = "serialize_to_true")]
184 IsNotEmpty,
185 LessThanOrEqualTo(Number),
186 LessThan(Number),
187}
188
189#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
190#[serde(rename_all = "snake_case")]
191pub enum PeopleCondition {
192 Contains(String),
193 DoesNotContain(String),
194 #[serde(serialize_with = "serialize_to_true")]
195 IsEmpty,
196 #[serde(serialize_with = "serialize_to_true")]
197 IsNotEmpty,
198}
199
200#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
201#[serde(rename_all = "snake_case")]
202pub enum RelationCondition {
203 Contains(String),
204 DoesNotContain(String),
205 #[serde(serialize_with = "serialize_to_true")]
206 IsEmpty,
207 #[serde(serialize_with = "serialize_to_true")]
208 IsNotEmpty,
209}
210
211#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
212#[serde(rename_all = "snake_case")]
213pub enum RichTextCondition {
214 Contains(String),
215 DoesNotContain(String),
216 DoesNotEqual(String),
217 EndsWith(String),
218 Equals(String),
219 #[serde(serialize_with = "serialize_to_true")]
220 IsEmpty,
221 #[serde(serialize_with = "serialize_to_true")]
222 IsNotEmpty,
223 StartsWith(String),
224}
225
226#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
227#[serde(rename_all = "snake_case")]
228pub enum RollupCondition {
229 Any(PropertyCondition),
230 Every(PropertyCondition),
231 None(PropertyCondition),
232 Date(DateCondition),
233 Number(NumberCondition),
234}
235
236#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
237#[serde(rename_all = "snake_case")]
238pub enum SelectCondition {
239 Equals(String),
240 DoesNotEqual(String),
241 #[serde(serialize_with = "serialize_to_true")]
242 IsEmpty,
243 #[serde(serialize_with = "serialize_to_true")]
244 IsNotEmpty,
245}
246
247#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
248#[serde(rename_all = "snake_case")]
249pub enum StatusCondition {
250 Equals(String),
251 DoesNotEqual(String),
252 #[serde(serialize_with = "serialize_to_true")]
253 IsEmpty,
254 #[serde(serialize_with = "serialize_to_true")]
255 IsNotEmpty,
256}
257
258#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
259#[serde(rename_all = "snake_case")]
260pub enum TimestampCondition {
261 CreatedTime(DateCondition),
262 LastEditedTime(DateCondition),
263}
264
265#[derive(Serialize, Debug, Eq, PartialEq, Clone)]
266#[serde(rename_all = "snake_case")]
267pub enum IDCondition {
268 DoesNotEqual(Number),
269 Equals(Number),
270 GreaterThan(Number),
271 GreaterThanOrEqualTo(Number),
272 LessThanOrEqualTo(Number),
273 LessThan(Number),
274}