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
26pub trait AnyImpl {
38 fn columns() -> Vec<AnyInfo>;
40
41 fn to_map(&self) -> HashMap<String, Option<String>>;
43}
44
45pub trait FromAnyRow: Sized {
47 fn from_any_row(row: &AnyRow) -> Result<Self, Error>;
49
50 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error>;
53}
54
55macro_rules! impl_supported_primitive {
60 ($($t:ty),*) => {
61 $(
62 impl AnyImpl for $t {
63 fn columns() -> Vec<AnyInfo> { Vec::new() }
64 fn to_map(&self) -> HashMap<String, Option<String>> { HashMap::new() }
65 }
66
67 impl FromAnyRow for $t {
68 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
69 row.try_get(0).map_err(|e| Error::Decode(Box::new(e)))
70 }
71
72 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
73 let val = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
74 *index += 1;
75 Ok(val)
76 }
77 }
78 )*
79 };
80}
81
82impl_supported_primitive!(bool, i16, i32, i64, f32, f64, String);
84
85macro_rules! impl_cast_primitive {
86 ($($t:ty),*) => {
87 $(
88 impl AnyImpl for $t {
89 fn columns() -> Vec<AnyInfo> { Vec::new() }
90 fn to_map(&self) -> HashMap<String, Option<String>> { HashMap::new() }
91 }
92
93 impl FromAnyRow for $t {
94 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
95 let val: i64 = row.try_get(0).map_err(|e| Error::Decode(Box::new(e)))?;
97 Ok(val as $t)
98 }
99
100 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
101 let val: i64 = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
102 *index += 1;
103 Ok(val as $t)
104 }
105 }
106 )*
107 };
108}
109
110impl_cast_primitive!(i8, isize, u8, u16, u32, u64, usize);
112
113impl<T> AnyImpl for Vec<T>
118where
119 T: AnyImpl + Serialize + for<'de> Deserialize<'de>,
120{
121 fn columns() -> Vec<AnyInfo> {
122 Vec::new()
123 }
124 fn to_map(&self) -> HashMap<String, Option<String>> {
125 let mut map = HashMap::new();
126 if let Ok(json) = serde_json::to_string(self) {
127 map.insert("".to_string(), Some(json));
128 }
129 map
130 }
131}
132
133impl<T> FromAnyRow for Vec<T>
134where
135 T: Serialize + for<'de> Deserialize<'de> + Send,
136{
137 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
138 let mut index = 0;
139 Self::from_any_row_at(row, &mut index)
140 }
141
142 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
143 let s: String = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
146 *index += 1;
147 serde_json::from_str(&s).map_err(|e| Error::Decode(Box::new(e)))
148 }
149}
150
151impl AnyImpl for serde_json::Value {
152 fn columns() -> Vec<AnyInfo> {
153 Vec::new()
154 }
155 fn to_map(&self) -> HashMap<String, Option<String>> {
156 let mut map = HashMap::new();
157 map.insert("".to_string(), Some(self.to_string()));
158 map
159 }
160}
161
162impl FromAnyRow for serde_json::Value {
163 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
164 let mut index = 0;
165 Self::from_any_row_at(row, &mut index)
166 }
167
168 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
169 let s: String = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
170 *index += 1;
171 serde_json::from_str(&s).map_err(|e| Error::Decode(Box::new(e)))
172 }
173}
174
175impl AnyImpl for uuid::Uuid {
180 fn columns() -> Vec<AnyInfo> {
181 Vec::new()
182 }
183 fn to_map(&self) -> HashMap<String, Option<String>> {
184 HashMap::new()
185 }
186}
187
188impl FromAnyRow for uuid::Uuid {
189 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
190 let mut index = 0;
191 Self::from_any_row_at(row, &mut index)
192 }
193
194 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
195 let s: String = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
196 *index += 1;
197 s.parse().map_err(|e| Error::Decode(Box::new(e)))
198 }
199}
200
201impl AnyImpl for chrono::NaiveDateTime {
202 fn columns() -> Vec<AnyInfo> {
203 Vec::new()
204 }
205 fn to_map(&self) -> HashMap<String, Option<String>> {
206 HashMap::new()
207 }
208}
209
210impl FromAnyRow for chrono::NaiveDateTime {
211 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
212 let mut index = 0;
213 Self::from_any_row_at(row, &mut index)
214 }
215
216 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
217 let res = row.try_get::<String, _>(*index);
218 match res {
219 Ok(s) => {
220 *index += 1;
221 crate::temporal::parse_naive_datetime(&s).map_err(|e| Error::Decode(Box::new(e)))
222 }
223 Err(e) => {
224 if let Ok(i) = row.try_get::<i64, _>(*index) {
226 *index += 1;
227 return Ok(chrono::DateTime::from_timestamp(i, 0).map(|dt| dt.naive_utc()).unwrap_or_default());
228 }
229 Err(Error::Decode(Box::new(e)))
230 }
231 }
232 }
233}
234
235impl AnyImpl for chrono::NaiveDate {
236 fn columns() -> Vec<AnyInfo> {
237 Vec::new()
238 }
239 fn to_map(&self) -> HashMap<String, Option<String>> {
240 HashMap::new()
241 }
242}
243
244impl FromAnyRow for chrono::NaiveDate {
245 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
246 let mut index = 0;
247 Self::from_any_row_at(row, &mut index)
248 }
249
250 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
251 let s: String = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
252 *index += 1;
253 crate::temporal::parse_naive_date(&s).map_err(|e| Error::Decode(Box::new(e)))
254 }
255}
256
257impl AnyImpl for chrono::NaiveTime {
258 fn columns() -> Vec<AnyInfo> {
259 Vec::new()
260 }
261 fn to_map(&self) -> HashMap<String, Option<String>> {
262 HashMap::new()
263 }
264}
265
266impl FromAnyRow for chrono::NaiveTime {
267 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
268 let mut index = 0;
269 Self::from_any_row_at(row, &mut index)
270 }
271
272 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
273 let s: String = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
274 *index += 1;
275 crate::temporal::parse_naive_time(&s).map_err(|e| Error::Decode(Box::new(e)))
276 }
277}
278
279impl AnyImpl for chrono::DateTime<chrono::Utc> {
280 fn columns() -> Vec<AnyInfo> {
281 Vec::new()
282 }
283 fn to_map(&self) -> HashMap<String, Option<String>> {
284 HashMap::new()
285 }
286}
287
288impl FromAnyRow for chrono::DateTime<chrono::Utc> {
289 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
290 let mut index = 0;
291 Self::from_any_row_at(row, &mut index)
292 }
293
294 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
295 let res = row.try_get::<String, _>(*index);
296 match res {
297 Ok(s) => {
298 *index += 1;
299 crate::temporal::parse_datetime_utc(&s).map_err(|e| Error::Decode(Box::new(e)))
300 }
301 Err(e) => {
302 if let Ok(i) = row.try_get::<i64, _>(*index) {
304 *index += 1;
305 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)));
306 }
307 Err(Error::Decode(Box::new(e)))
308 }
309 }
310 }
311}
312
313impl<T: AnyImpl> AnyImpl for Option<T> {
318 fn columns() -> Vec<AnyInfo> {
319 T::columns()
320 }
321 fn to_map(&self) -> HashMap<String, Option<String>> {
322 match self {
323 Some(v) => v.to_map(),
324 None => HashMap::new(),
325 }
326 }
327}
328
329impl<T: FromAnyRow> FromAnyRow for Option<T> {
330 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
331 match T::from_any_row(row) {
332 Ok(v) => Ok(Some(v)),
333 Err(_) => Ok(None),
334 }
335 }
336
337 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
338 match T::from_any_row_at(row, index) {
339 Ok(v) => Ok(Some(v)),
340 Err(_) => Ok(None),
341 }
342 }
343}
344
345macro_rules! impl_any_tuple {
350 ($($T:ident),+) => {
351 impl<$($T: AnyImpl),+> AnyImpl for ($($T,)+) {
352 fn columns() -> Vec<AnyInfo> {
353 let mut cols = Vec::new();
354 $(
355 cols.extend($T::columns());
356 )+
357 cols
358 }
359
360 fn to_map(&self) -> HashMap<String, Option<String>> {
361 let mut map = HashMap::new();
362 #[allow(non_snake_case)]
363 let ($($T,)+) = self;
364 $(
365 map.extend($T.to_map());
366 )+
367 map
368 }
369 }
370
371 impl<$($T: FromAnyRow),+> FromAnyRow for ($($T,)+) {
372 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
373 let mut index = 0;
374 Ok((
375 $(
376 $T::from_any_row_at(row, &mut index)?,
377 )+
378 ))
379 }
380
381 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
382 Ok((
383 $(
384 $T::from_any_row_at(row, index)?,
385 )+
386 ))
387 }
388 }
389 };
390}
391
392impl_any_tuple!(T1);
393impl_any_tuple!(T1, T2);
394impl_any_tuple!(T1, T2, T3);
395impl_any_tuple!(T1, T2, T3, T4);
396impl_any_tuple!(T1, T2, T3, T4, T5);
397impl_any_tuple!(T1, T2, T3, T4, T5, T6);
398impl_any_tuple!(T1, T2, T3, T4, T5, T6, T7);
399impl_any_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);