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)))?;
128 Ok(val as $t)
129 }
130
131 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
132 if *index >= row.len() {
133 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
134 }
135 let res = row.try_get::<i64, _>(*index);
136 *index += 1;
137 let val = res.map_err(|e| Error::Decode(Box::new(e)))?;
138 Ok(val as $t)
139 }
140 }
141 )*
142 };
143}
144
145impl_cast_primitive!(i8, isize, u8, u16, u32, u64, usize);
147
148impl<T> AnyImpl for Vec<T>
153where
154 T: AnyImpl + Serialize + for<'de> Deserialize<'de>,
155{
156 fn columns() -> Vec<AnyInfo> {
157 Vec::new()
158 }
159 fn to_map(&self) -> HashMap<String, Option<String>> {
160 let mut map = HashMap::new();
161 if let Ok(json) = serde_json::to_string(self) {
162 map.insert("".to_string(), Some(json));
163 }
164 map
165 }
166}
167
168impl<T> FromAnyRow for Vec<T>
169where
170 T: Serialize + for<'de> Deserialize<'de> + Send,
171{
172 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
173 let mut index = 0;
174 Self::from_any_row_at(row, &mut index)
175 }
176
177 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
178 if *index >= row.len() {
179 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
180 }
181 let res = row.try_get::<String, _>(*index);
182 *index += 1;
183 let s = res.map_err(|e| Error::Decode(Box::new(e)))?;
184 serde_json::from_str(&s).map_err(|e| Error::Decode(Box::new(e)))
185 }
186}
187
188impl AnyImpl for serde_json::Value {
189 fn columns() -> Vec<AnyInfo> {
190 Vec::new()
191 }
192 fn to_map(&self) -> HashMap<String, Option<String>> {
193 let mut map = HashMap::new();
194 map.insert("".to_string(), Some(self.to_string()));
195 map
196 }
197}
198
199impl FromAnyRow for serde_json::Value {
200 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
201 let mut index = 0;
202 Self::from_any_row_at(row, &mut index)
203 }
204
205 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
206 if *index >= row.len() {
207 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
208 }
209 let res = row.try_get::<String, _>(*index);
210 *index += 1;
211 let s = res.map_err(|e| Error::Decode(Box::new(e)))?;
212 serde_json::from_str(&s).map_err(|e| Error::Decode(Box::new(e)))
213 }
214}
215
216impl AnyImpl for uuid::Uuid {
221 fn columns() -> Vec<AnyInfo> {
222 Vec::new()
223 }
224 fn to_map(&self) -> HashMap<String, Option<String>> {
225 HashMap::new()
226 }
227}
228
229impl FromAnyRow for uuid::Uuid {
230 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
231 let mut index = 0;
232 Self::from_any_row_at(row, &mut index)
233 }
234
235 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
236 if *index >= row.len() {
237 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
238 }
239 let res = row.try_get::<String, _>(*index);
240 *index += 1;
241 let s = res.map_err(|e| Error::Decode(Box::new(e)))?;
242 s.parse().map_err(|e| Error::Decode(Box::new(e)))
243 }
244}
245
246impl AnyImpl for chrono::NaiveDateTime {
247 fn columns() -> Vec<AnyInfo> {
248 Vec::new()
249 }
250 fn to_map(&self) -> HashMap<String, Option<String>> {
251 HashMap::new()
252 }
253}
254
255impl FromAnyRow for chrono::NaiveDateTime {
256 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
257 let mut index = 0;
258 Self::from_any_row_at(row, &mut index)
259 }
260
261 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
262 if *index >= row.len() {
263 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
264 }
265 let res = row.try_get::<String, _>(*index);
266 match res {
267 Ok(s) => {
268 *index += 1;
269 crate::temporal::parse_naive_datetime(&s).map_err(|e| Error::Decode(Box::new(e)))
270 }
271 Err(e) => {
272 if let Ok(i) = row.try_get::<i64, _>(*index) {
274 *index += 1;
275 return Ok(chrono::DateTime::from_timestamp(i, 0).map(|dt| dt.naive_utc()).unwrap_or_default());
276 }
277 if let Ok(None) = row.try_get::<Option<String>, _>(*index) {
281 *index += 1;
282 return Err(Error::Decode(Box::new(e))); }
284
285 Err(Error::Decode(Box::new(e)))
286 }
287 }
288 }
289}
290
291impl AnyImpl for chrono::NaiveDate {
292 fn columns() -> Vec<AnyInfo> {
293 Vec::new()
294 }
295 fn to_map(&self) -> HashMap<String, Option<String>> {
296 HashMap::new()
297 }
298}
299
300impl FromAnyRow for chrono::NaiveDate {
301 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
302 let mut index = 0;
303 Self::from_any_row_at(row, &mut index)
304 }
305
306 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
307 if *index >= row.len() {
308 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
309 }
310 let res = row.try_get::<String, _>(*index);
311 *index += 1;
312 let s = res.map_err(|e| Error::Decode(Box::new(e)))?;
313 crate::temporal::parse_naive_date(&s).map_err(|e| Error::Decode(Box::new(e)))
314 }
315}
316
317impl AnyImpl for chrono::NaiveTime {
318 fn columns() -> Vec<AnyInfo> {
319 Vec::new()
320 }
321 fn to_map(&self) -> HashMap<String, Option<String>> {
322 HashMap::new()
323 }
324}
325
326impl FromAnyRow for chrono::NaiveTime {
327 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
328 let mut index = 0;
329 Self::from_any_row_at(row, &mut index)
330 }
331
332 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
333 if *index >= row.len() {
334 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
335 }
336 let res = row.try_get::<String, _>(*index);
337 *index += 1;
338 let s = res.map_err(|e| Error::Decode(Box::new(e)))?;
339 crate::temporal::parse_naive_time(&s).map_err(|e| Error::Decode(Box::new(e)))
340 }
341}
342
343impl AnyImpl for chrono::DateTime<chrono::Utc> {
344 fn columns() -> Vec<AnyInfo> {
345 Vec::new()
346 }
347 fn to_map(&self) -> HashMap<String, Option<String>> {
348 HashMap::new()
349 }
350}
351
352impl FromAnyRow for chrono::DateTime<chrono::Utc> {
353 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
354 let mut index = 0;
355 Self::from_any_row_at(row, &mut index)
356 }
357
358 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
359 if *index >= row.len() {
360 return Err(Error::ColumnIndexOutOfBounds { index: *index, len: row.len() });
361 }
362 let res = row.try_get::<String, _>(*index);
363 match res {
364 Ok(s) => {
365 *index += 1;
366 crate::temporal::parse_datetime_utc(&s).map_err(|e| Error::Decode(Box::new(e)))
367 }
368 Err(e) => {
369 if let Ok(i) = row.try_get::<i64, _>(*index) {
371 *index += 1;
372 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)));
373 }
374
375 if let Ok(None) = row.try_get::<Option<String>, _>(*index) {
376 *index += 1;
377 return Err(Error::Decode(Box::new(e)));
378 }
379
380 Err(Error::Decode(Box::new(e)))
381 }
382 }
383 }
384}
385
386impl<T: AnyImpl> AnyImpl for Option<T> {
391 fn columns() -> Vec<AnyInfo> {
392 T::columns()
393 }
394 fn to_map(&self) -> HashMap<String, Option<String>> {
395 match self {
396 Some(v) => v.to_map(),
397 None => HashMap::new(),
398 }
399 }
400}
401
402impl<T: FromAnyRow> FromAnyRow for Option<T> {
403 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
404 match T::from_any_row(row) {
405 Ok(v) => Ok(Some(v)),
406 Err(_) => Ok(None),
407 }
408 }
409
410 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
411 match T::from_any_row_at(row, index) {
412 Ok(v) => Ok(Some(v)),
413 Err(_) => Ok(None),
414 }
415 }
416}
417
418macro_rules! impl_any_tuple {
423 ($($T:ident),+) => {
424 impl<$($T: AnyImpl),+> AnyImpl for ($($T,)+) {
425 fn columns() -> Vec<AnyInfo> {
426 let mut cols = Vec::new();
427 $(
428 cols.extend($T::columns());
429 )+
430 cols
431 }
432
433 fn to_map(&self) -> HashMap<String, Option<String>> {
434 let mut map = HashMap::new();
435 #[allow(non_snake_case)]
436 let ($($T,)+) = self;
437 $(
438 map.extend($T.to_map());
439 )+
440 map
441 }
442 }
443
444 impl<$($T: FromAnyRow),+> FromAnyRow for ($($T,)+) {
445 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
446 let mut index = 0;
447 Ok((
448 $(
449 $T::from_any_row_at(row, &mut index)?,
450 )+
451 ))
452 }
453
454 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
455 Ok((
456 $(
457 $T::from_any_row_at(row, index)?,
458 )+
459 ))
460 }
461 }
462 };
463}
464
465impl_any_tuple!(T1);
466impl_any_tuple!(T1, T2);
467impl_any_tuple!(T1, T2, T3);
468impl_any_tuple!(T1, T2, T3, T4);
469impl_any_tuple!(T1, T2, T3, T4, T5);
470impl_any_tuple!(T1, T2, T3, T4, T5, T6);
471impl_any_tuple!(T1, T2, T3, T4, T5, T6, T7);
472impl_any_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);