1mod query;
2
3use async_trait::async_trait;
4use std::collections::HashMap;
5
6pub use firestore_grpc;
7
8pub mod store_field;
9
10use firestore_grpc::v1::{
11 structured_query::{
12 filter::FilterType, FieldFilter, FieldReference, Filter as QueryFilter, Order,
13 },
14 value::ValueType,
15 Cursor, Document, Value as FsValue,
16};
17
18#[derive(Debug, Default)]
19pub struct State {
20 token: Option<String>,
21 project_id: String,
22 collection: String,
23 document: String,
24 where_field: Vec<QueryFilter>,
25 order_by: Vec<firestore_grpc::v1::structured_query::Order>,
26 start_at: Option<Cursor>,
27 end_at: Option<Cursor>,
28 limit: Option<i32>,
30}
31
32pub struct Direction;
33impl Direction {
34 pub const ASCENDING: i32 = 1;
35 pub const DESCENDING: i32 = 2;
36}
37
38pub struct Operator;
39impl Operator {
40 pub const LESS_THAN: i32 = 1;
41 pub const LESS_THAN_OR_EQUAL: i32 = 2;
42 pub const GREATER_THAN: i32 = 3;
43 pub const GREATER_THAN_OR_EQUAL: i32 = 4;
44 pub const EQUAL: i32 = 5;
45 pub const NOT_EQUAL: i32 = 6;
46 pub const ARRAY_CONTAINS: i32 = 7;
47 pub const IN: i32 = 8;
48 pub const ARRAY_CONTAINS_ANY: i32 = 9;
49 pub const NOT_IN: i32 = 10;
50}
51
52pub type BoxError = Box<dyn std::error::Error + Sync + Send + 'static>;
53
54#[async_trait]
55pub trait FireStore {
56 fn init(&mut self, project_id: &str, token: Option<&str>) -> &mut Self;
57 fn collection(&mut self, collection: &str) -> &mut Self;
58 fn document(&mut self, document: &str) -> &mut Self;
59 fn where_field(&mut self, field: &str, operator: i32, value: ValueType) -> &mut Self;
60 fn order_by(&mut self, field: &str, direction: i32) -> &mut Self;
61 fn start_at(&mut self, document: Document) -> &mut Self;
62 fn start_after(&mut self, document: Document) -> &mut Self;
63 fn end_before(&mut self, document: Document) -> &mut Self;
64 fn end_at(&mut self, document: Document) -> &mut Self;
65 fn limit(&mut self, limit: i32) -> &mut Self;
67 async fn get_document(&mut self) -> Result<Document, BoxError>;
68 async fn get_documents(&mut self) -> Result<Vec<Document>, BoxError>;
69 async fn set_document(
70 &mut self,
71 document_id: &str,
72 fields: HashMap<String, FsValue>,
73 ) -> Result<Document, BoxError>;
74 async fn add_document(
75 &mut self,
76 fields: HashMap<String, FsValue>,
77 ) -> Result<Document, BoxError>;
78 async fn delete(&mut self) -> Result<String, BoxError>;
79}
80
81#[async_trait]
82impl FireStore for State {
83 fn init(&mut self, project_id: &str, token: Option<&str>) -> &mut Self {
84 self.project_id = project_id.to_string();
85 self.token = match token {
86 Some(token) => Some(token.to_string()),
87 None => None,
88 };
89
90 self
91 }
92
93 fn collection(&mut self, collection: &str) -> &mut Self {
94 self.collection = collection.to_string();
95 self
96 }
97
98 fn document(&mut self, document: &str) -> &mut Self {
99 self.document = document.to_string();
100 self
101 }
102
103 fn where_field(&mut self, field: &str, operator: i32, value: ValueType) -> &mut Self {
104 let field_filter = FieldFilter {
105 field: Some(FieldReference {
106 field_path: field.to_string(),
107 }),
108 op: operator,
109 value: Some(FsValue {
110 value_type: Some(value),
111 }),
112 };
113
114 self.where_field.push(QueryFilter {
115 filter_type: Some(FilterType::FieldFilter(field_filter)),
116 });
117
118 self
119 }
120
121 fn order_by(&mut self, field: &str, direction: i32) -> &mut Self {
122 self.order_by.push(Order {
123 field: Some(FieldReference {
124 field_path: field.to_string(),
125 }),
126 direction,
127 });
128 self
129 }
130
131 fn start_at(&mut self, document: Document) -> &mut Self {
132 let mut cursor_values = Vec::new();
133
134 for order_by in self.order_by.clone() {
135 let field_path = order_by.field.unwrap().field_path;
136 cursor_values.push(document.fields.get(&field_path).unwrap().clone());
137 }
138
139 self.order_by.push(Order {
140 field: Some(FieldReference {
141 field_path: "__name__".to_string(),
142 }),
143 direction: Direction::ASCENDING,
144 });
145
146 cursor_values.push(store_field::Value::reference(document.name));
147
148 self.start_at = Some(Cursor {
149 values: cursor_values,
150 before: true,
151 });
152
153 self
154 }
155
156 fn start_after(&mut self, document: Document) -> &mut Self {
157 let mut cursor_values = Vec::new();
158
159 for order_by in self.order_by.clone() {
160 let field_path = order_by.field.unwrap().field_path;
161 cursor_values.push(document.fields.get(&field_path).unwrap().clone());
162 }
163
164 self.order_by.push(Order {
165 field: Some(FieldReference {
166 field_path: "__name__".to_string(),
167 }),
168 direction: Direction::ASCENDING,
169 });
170
171 cursor_values.push(store_field::Value::reference(document.name));
172
173 self.start_at = Some(Cursor {
174 values: cursor_values,
175 before: false,
176 });
177
178 self
179 }
180
181 fn end_before(&mut self, document: Document) -> &mut Self {
182 let mut cursor_values = Vec::new();
183
184 for order_by in self.order_by.clone() {
185 let field_path = order_by.field.unwrap().field_path;
186 cursor_values.push(document.fields.get(&field_path).unwrap().clone());
187 }
188
189 self.order_by.push(Order {
190 field: Some(FieldReference {
191 field_path: "__name__".to_string(),
192 }),
193 direction: Direction::ASCENDING,
194 });
195
196 cursor_values.push(store_field::Value::reference(document.name));
197
198 self.end_at = Some(Cursor {
199 values: cursor_values,
200 before: true,
201 });
202 self
203 }
204
205 fn end_at(&mut self, document: Document) -> &mut Self {
206 let mut cursor_values = Vec::new();
207
208 for order_by in self.order_by.clone() {
209 let field_path = order_by.field.unwrap().field_path;
210 cursor_values.push(document.fields.get(&field_path).unwrap().clone());
211 }
212
213 self.order_by.push(Order {
214 field: Some(FieldReference {
215 field_path: "__name__".to_string(),
216 }),
217 direction: Direction::ASCENDING,
218 });
219
220 cursor_values.push(store_field::Value::reference(document.name));
221
222 self.end_at = Some(Cursor {
223 values: cursor_values,
224 before: false,
225 });
226 self
227 }
228
229 fn limit(&mut self, limit: i32) -> &mut Self {
236 self.limit = Some(limit);
237 self
238 }
239
240 async fn get_document(&mut self) -> Result<Document, BoxError> {
241 let res = query::get_document(self).await;
242 Ok(res.unwrap().into_inner())
243 }
244
245 async fn get_documents(&mut self) -> Result<Vec<Document>, BoxError> {
246 let res = query::run_query(self).await;
247 let mut stream = res.unwrap().into_inner();
248
249 let mut vec = Vec::new();
250
251 loop {
252 let item = stream.message().await?;
253 match item {
254 Some(_) => {
255 let document = item.unwrap().document;
256 match document {
257 Some(document) => vec.push(document),
258 None => break,
259 }
260 }
261 None => break,
262 }
263 }
264
265 Ok(vec)
266 }
267
268 async fn set_document(
269 &mut self,
270 document_id: &str,
271 fields: HashMap<String, FsValue>,
272 ) -> Result<Document, BoxError> {
273 let exists = query::get_document(self).await;
274
275 let res;
276
277 match exists {
278 Ok(_) => res = query::update_document(self, document_id, fields).await,
279 Err(_) => res = query::create_document(self, document_id, fields).await,
280 };
281
282 Ok(res.unwrap().into_inner())
283 }
284
285 async fn add_document(
286 &mut self,
287 fields: HashMap<String, FsValue>,
288 ) -> Result<Document, BoxError> {
289 let res = query::create_document(self, "".into(), fields).await;
290
291 Ok(res.unwrap().into_inner())
292 }
293
294 async fn delete(&mut self) -> Result<String, BoxError> {
295 query::delete_document(self).await.unwrap();
296
297 Ok(self.document.clone())
298 }
299}
300
301pub fn db() -> State {
302 State::default()
303}