1use sqlx::{any::AnyRow, Error, Row};
2use std::collections::HashMap;
3use serde::{Serialize, Deserialize};
4
5#[derive(Debug, Clone)]
15pub struct AnyInfo {
16 pub column: &'static str,
18
19 pub sql_type: &'static str,
21
22 pub table: &'static str,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct AnyImplStruct {}
30
31impl AnyImpl for AnyImplStruct {
32 fn columns() -> Vec<AnyInfo> { Vec::new() }
33 fn to_map(&self) -> HashMap<String, Option<String>> { HashMap::new() }
34}
35
36impl FromAnyRow for AnyImplStruct {
37 fn from_any_row(_row: &AnyRow) -> Result<Self, Error> { Ok(AnyImplStruct {}) }
38 fn from_any_row_at(_row: &AnyRow, _index: &mut usize) -> Result<Self, Error> { Ok(AnyImplStruct {}) }
39}
40
41impl crate::model::Model for AnyImplStruct {
42 fn table_name() -> &'static str { "" }
43 fn columns() -> Vec<crate::model::ColumnInfo> { Vec::new() }
44 fn column_names() -> Vec<String> { Vec::new() }
45 fn active_columns() -> Vec<&'static str> { Vec::new() }
46 fn relations() -> Vec<crate::model::RelationInfo> { Vec::new() }
47 fn load_relations<'a>(
48 _relation_name: &'a str,
49 _models: &'a mut [Self],
50 _tx: &'a dyn crate::database::Connection,
51 _query_modifier: Option<std::sync::Arc<dyn std::any::Any + Send + Sync>>,
52 ) -> futures::future::BoxFuture<'a, Result<(), sqlx::Error>> {
53 Box::pin(async move { Ok(()) })
54 }
55 fn to_map(&self) -> HashMap<String, Option<String>> { HashMap::new() }
56}
57
58pub trait AnyImpl {
66 fn columns() -> Vec<AnyInfo>;
68
69 fn to_map(&self) -> HashMap<String, Option<String>>;
71}
72
73pub trait FromAnyRow: Sized {
75 fn from_any_row(row: &AnyRow) -> Result<Self, Error>;
77
78 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error>;
81}
82
83macro_rules! impl_supported_primitive {
88 ($($t:ty),*) => {
89 $(
90 impl AnyImpl for $t {
91 fn columns() -> Vec<AnyInfo> { Vec::new() }
92 fn to_map(&self) -> HashMap<String, Option<String>> { HashMap::new() }
93 }
94
95 impl FromAnyRow for $t {
96 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
97 row.try_get(0).map_err(|e| Error::Decode(Box::new(e)))
98 }
99
100 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
101 if *index >= row.len() {
102 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
103 }
104 let res = row.try_get(*index);
105 *index += 1;
106 res.map_err(|e| Error::Decode(Box::new(e)))
107 }
108 }
109 )*
110 };
111}
112
113impl_supported_primitive!(bool, i16, i32, i64, f32, f64, String);
115
116macro_rules! impl_cast_primitive {
117 ($($t:ty),*) => {
118 $(
119 impl AnyImpl for $t {
120 fn columns() -> Vec<AnyInfo> { Vec::new() }
121 fn to_map(&self) -> HashMap<String, Option<String>> { HashMap::new() }
122 }
123
124 impl FromAnyRow for $t {
125 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
126 let val: i64 = row.try_get(0).map_err(|e| Error::Decode(Box::new(e)))?;
127 <$t>::try_from(val).map_err(|e| Error::Decode(Box::new(e)))
128 }
129
130 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
131 if *index >= row.len() {
132 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
133 }
134 let res = row.try_get::<i64, _>(*index);
135 *index += 1;
136 let val = res.map_err(|e| Error::Decode(Box::new(e)))?;
137 <$t>::try_from(val).map_err(|e| Error::Decode(Box::new(e)))
138 }
139 }
140 )*
141 };
142}
143
144impl_cast_primitive!(i8, isize, u8, u16, u32, u64, usize);
146
147impl<T> AnyImpl for Vec<T>
152where
153 T: AnyImpl + Serialize + for<'de> Deserialize<'de>,
154{
155 fn columns() -> Vec<AnyInfo> {
156 Vec::new()
157 }
158 fn to_map(&self) -> HashMap<String, Option<String>> {
159 let mut map = HashMap::new();
160 if let Ok(json) = serde_json::to_string(self) {
161 map.insert("".to_string(), Some(json));
162 }
163 map
164 }
165}
166
167impl<T> FromAnyRow for Vec<T>
168where
169 T: Serialize + for<'de> Deserialize<'de> + Send,
170{
171 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
172 let mut index = 0;
173 Self::from_any_row_at(row, &mut index)
174 }
175
176 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
177 if *index >= row.len() {
178 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
179 }
180 let res = row.try_get::<String, _>(*index);
181 *index += 1;
182 let s = res.map_err(|e| Error::Decode(Box::new(e)))?;
183 serde_json::from_str(&s).map_err(|e| Error::Decode(Box::new(e)))
184 }
185}
186
187impl AnyImpl for serde_json::Value {
188 fn columns() -> Vec<AnyInfo> {
189 Vec::new()
190 }
191 fn to_map(&self) -> HashMap<String, Option<String>> {
192 let mut map = HashMap::new();
193 map.insert("".to_string(), Some(self.to_string()));
194 map
195 }
196}
197
198impl FromAnyRow for serde_json::Value {
199 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
200 let mut index = 0;
201 Self::from_any_row_at(row, &mut index)
202 }
203
204 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
205 if *index >= row.len() {
206 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
207 }
208 let res = row.try_get::<String, _>(*index);
209 *index += 1;
210 let s = res.map_err(|e| Error::Decode(Box::new(e)))?;
211 serde_json::from_str(&s).map_err(|e| Error::Decode(Box::new(e)))
212 }
213}
214
215impl AnyImpl for uuid::Uuid {
220 fn columns() -> Vec<AnyInfo> {
221 Vec::new()
222 }
223 fn to_map(&self) -> HashMap<String, Option<String>> {
224 HashMap::new()
225 }
226}
227
228impl FromAnyRow for uuid::Uuid {
229 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
230 let mut index = 0;
231 Self::from_any_row_at(row, &mut index)
232 }
233
234 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
235 if *index >= row.len() {
236 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
237 }
238 let res = row.try_get::<String, _>(*index);
239 *index += 1;
240 let s = res.map_err(|e| Error::Decode(Box::new(e)))?;
241 s.parse().map_err(|e| Error::Decode(Box::new(e)))
242 }
243}
244
245impl AnyImpl for chrono::NaiveDateTime {
246 fn columns() -> Vec<AnyInfo> {
247 Vec::new()
248 }
249 fn to_map(&self) -> HashMap<String, Option<String>> {
250 HashMap::new()
251 }
252}
253
254impl FromAnyRow for chrono::NaiveDateTime {
255 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
256 let mut index = 0;
257 Self::from_any_row_at(row, &mut index)
258 }
259
260 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
261 if *index >= row.len() {
262 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
263 }
264 let res = row.try_get::<String, _>(*index);
265 match res {
266 Ok(s) => {
267 *index += 1;
268 crate::temporal::parse_naive_datetime(&s).map_err(|e| Error::Decode(Box::new(e)))
269 }
270 Err(e) => {
271 if let Ok(i) = row.try_get::<i64, _>(*index) {
273 *index += 1;
274 return Ok(chrono::DateTime::from_timestamp(i, 0).map(|dt| dt.naive_utc()).unwrap_or_default());
275 }
276 if let Ok(None) = row.try_get::<Option<String>, _>(*index) {
280 *index += 1;
281 return Err(Error::Decode(Box::new(e))); }
283
284 Err(Error::Decode(Box::new(e)))
285 }
286 }
287 }
288}
289
290impl AnyImpl for chrono::NaiveDate {
291 fn columns() -> Vec<AnyInfo> {
292 Vec::new()
293 }
294 fn to_map(&self) -> HashMap<String, Option<String>> {
295 HashMap::new()
296 }
297}
298
299impl FromAnyRow for chrono::NaiveDate {
300 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
301 let mut index = 0;
302 Self::from_any_row_at(row, &mut index)
303 }
304
305 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
306 if *index >= row.len() {
307 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
308 }
309 let res = row.try_get::<String, _>(*index);
310 *index += 1;
311 let s = res.map_err(|e| Error::Decode(Box::new(e)))?;
312 crate::temporal::parse_naive_date(&s).map_err(|e| Error::Decode(Box::new(e)))
313 }
314}
315
316impl AnyImpl for chrono::NaiveTime {
317 fn columns() -> Vec<AnyInfo> {
318 Vec::new()
319 }
320 fn to_map(&self) -> HashMap<String, Option<String>> {
321 HashMap::new()
322 }
323}
324
325impl FromAnyRow for chrono::NaiveTime {
326 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
327 let mut index = 0;
328 Self::from_any_row_at(row, &mut index)
329 }
330
331 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
332 if *index >= row.len() {
333 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
334 }
335 let res = row.try_get::<String, _>(*index);
336 *index += 1;
337 let s = res.map_err(|e| Error::Decode(Box::new(e)))?;
338 crate::temporal::parse_naive_time(&s).map_err(|e| Error::Decode(Box::new(e)))
339 }
340}
341
342impl AnyImpl for chrono::DateTime<chrono::Utc> {
343 fn columns() -> Vec<AnyInfo> {
344 Vec::new()
345 }
346 fn to_map(&self) -> HashMap<String, Option<String>> {
347 HashMap::new()
348 }
349}
350
351impl FromAnyRow for chrono::DateTime<chrono::Utc> {
352 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
353 let mut index = 0;
354 Self::from_any_row_at(row, &mut index)
355 }
356
357 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
358 if *index >= row.len() {
359 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
360 }
361 let res = row.try_get::<String, _>(*index);
362 match res {
363 Ok(s) => {
364 *index += 1;
365 crate::temporal::parse_datetime_utc(&s).map_err(|e| Error::Decode(Box::new(e)))
366 }
367 Err(e) => {
368 if let Ok(i) = row.try_get::<i64, _>(*index) {
370 *index += 1;
371 return Ok(chrono::DateTime::from_timestamp(i, 0).unwrap_or_else(|| chrono::DateTime::<chrono::Utc>::from_naive_utc_and_offset(chrono::NaiveDateTime::default(), chrono::Utc)));
372 }
373
374 if let Ok(None) = row.try_get::<Option<String>, _>(*index) {
375 *index += 1;
376 return Err(Error::Decode(Box::new(e)));
377 }
378
379 Err(Error::Decode(Box::new(e)))
380 }
381 }
382 }
383}
384
385impl<T: AnyImpl> AnyImpl for Option<T> {
390 fn columns() -> Vec<AnyInfo> {
391 T::columns()
392 }
393 fn to_map(&self) -> HashMap<String, Option<String>> {
394 match self {
395 Some(v) => v.to_map(),
396 None => HashMap::new(),
397 }
398 }
399}
400
401impl<T: FromAnyRow> FromAnyRow for Option<T> {
402 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
403 match T::from_any_row(row) {
404 Ok(v) => Ok(Some(v)),
405 Err(_) => Ok(None),
406 }
407 }
408
409 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
410 match T::from_any_row_at(row, index) {
411 Ok(v) => Ok(Some(v)),
412 Err(_) => Ok(None),
413 }
414 }
415}
416
417macro_rules! impl_any_tuple {
422 ($($T:ident),+) => {
423 impl<$($T: AnyImpl),+> AnyImpl for ($($T,)+) {
424 fn columns() -> Vec<AnyInfo> {
425 let mut cols = Vec::new();
426 $(
427 cols.extend($T::columns());
428 )+
429 cols
430 }
431
432 fn to_map(&self) -> HashMap<String, Option<String>> {
433 let mut map = HashMap::new();
434 #[allow(non_snake_case)]
435 let ($($T,)+) = self;
436 $(
437 map.extend($T.to_map());
438 )+
439 map
440 }
441 }
442
443 impl<$($T: FromAnyRow),+> FromAnyRow for ($($T,)+) {
444 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
445 let mut index = 0;
446 Ok((
447 $(
448 $T::from_any_row_at(row, &mut index)?,
449 )+
450 ))
451 }
452
453 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
454 Ok((
455 $(
456 $T::from_any_row_at(row, index)?,
457 )+
458 ))
459 }
460 }
461 };
462}
463
464impl_any_tuple!(T1);
465impl_any_tuple!(T1, T2);
466impl_any_tuple!(T1, T2, T3);
467impl_any_tuple!(T1, T2, T3, T4);
468impl_any_tuple!(T1, T2, T3, T4, T5);
469impl_any_tuple!(T1, T2, T3, T4, T5, T6);
470impl_any_tuple!(T1, T2, T3, T4, T5, T6, T7);
471impl_any_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);