1use sqlx::{any::AnyRow, Error, Row};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone)]
14pub struct AnyInfo {
15 pub column: &'static str,
17
18 pub sql_type: &'static str,
20
21 pub table: &'static str,
23}
24
25pub trait AnyImpl {
37 fn columns() -> Vec<AnyInfo>;
39
40 fn to_map(&self) -> HashMap<String, String>;
42}
43
44pub trait FromAnyRow: Sized {
46 fn from_any_row(row: &AnyRow) -> Result<Self, Error>;
48
49 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error>;
52}
53
54macro_rules! impl_supported_primitive {
59 ($($t:ty),*) => {
60 $(
61 impl AnyImpl for $t {
62 fn columns() -> Vec<AnyInfo> { Vec::new() }
63 fn to_map(&self) -> HashMap<String, String> { HashMap::new() }
64 }
65
66 impl FromAnyRow for $t {
67 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
68 row.try_get(0).map_err(|e| Error::Decode(Box::new(e)))
69 }
70
71 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
72 let val = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
73 *index += 1;
74 Ok(val)
75 }
76 }
77 )*
78 };
79}
80
81impl_supported_primitive!(bool, i16, i32, i64, f32, f64, String);
83
84macro_rules! impl_cast_primitive {
85 ($($t:ty),*) => {
86 $(
87 impl AnyImpl for $t {
88 fn columns() -> Vec<AnyInfo> { Vec::new() }
89 fn to_map(&self) -> HashMap<String, String> { HashMap::new() }
90 }
91
92 impl FromAnyRow for $t {
93 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
94 let val: i64 = row.try_get(0).map_err(|e| Error::Decode(Box::new(e)))?;
96 Ok(val as $t)
97 }
98
99 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
100 let val: i64 = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
101 *index += 1;
102 Ok(val as $t)
103 }
104 }
105 )*
106 };
107}
108
109impl_cast_primitive!(i8, isize, u8, u16, u32, u64, usize);
111
112impl AnyImpl for uuid::Uuid {
117 fn columns() -> Vec<AnyInfo> {
118 Vec::new()
119 }
120 fn to_map(&self) -> HashMap<String, String> {
121 HashMap::new()
122 }
123}
124
125impl FromAnyRow for uuid::Uuid {
126 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
127 let mut index = 0;
128 Self::from_any_row_at(row, &mut index)
129 }
130
131 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
132 let s: String = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
133 *index += 1;
134 s.parse().map_err(|e| Error::Decode(Box::new(e)))
135 }
136}
137
138impl AnyImpl for chrono::NaiveDateTime {
139 fn columns() -> Vec<AnyInfo> {
140 Vec::new()
141 }
142 fn to_map(&self) -> HashMap<String, String> {
143 HashMap::new()
144 }
145}
146
147impl FromAnyRow for chrono::NaiveDateTime {
148 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
149 let mut index = 0;
150 Self::from_any_row_at(row, &mut index)
151 }
152
153 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
154 let res = row.try_get::<String, _>(*index);
155 match res {
156 Ok(s) => {
157 *index += 1;
158 crate::temporal::parse_naive_datetime(&s).map_err(|e| Error::Decode(Box::new(e)))
159 }
160 Err(e) => {
161 if let Ok(i) = row.try_get::<i64, _>(*index) {
163 *index += 1;
164 return Ok(chrono::DateTime::from_timestamp(i, 0).map(|dt| dt.naive_utc()).unwrap_or_default());
165 }
166 Err(Error::Decode(Box::new(e)))
167 }
168 }
169 }
170}
171
172impl AnyImpl for chrono::NaiveDate {
173 fn columns() -> Vec<AnyInfo> {
174 Vec::new()
175 }
176 fn to_map(&self) -> HashMap<String, String> {
177 HashMap::new()
178 }
179}
180
181impl FromAnyRow for chrono::NaiveDate {
182 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
183 let mut index = 0;
184 Self::from_any_row_at(row, &mut index)
185 }
186
187 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
188 let s: String = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
189 *index += 1;
190 crate::temporal::parse_naive_date(&s).map_err(|e| Error::Decode(Box::new(e)))
191 }
192}
193
194impl AnyImpl for chrono::NaiveTime {
195 fn columns() -> Vec<AnyInfo> {
196 Vec::new()
197 }
198 fn to_map(&self) -> HashMap<String, String> {
199 HashMap::new()
200 }
201}
202
203impl FromAnyRow for chrono::NaiveTime {
204 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
205 let mut index = 0;
206 Self::from_any_row_at(row, &mut index)
207 }
208
209 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
210 let s: String = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
211 *index += 1;
212 crate::temporal::parse_naive_time(&s).map_err(|e| Error::Decode(Box::new(e)))
213 }
214}
215
216impl AnyImpl for chrono::DateTime<chrono::Utc> {
217 fn columns() -> Vec<AnyInfo> {
218 Vec::new()
219 }
220 fn to_map(&self) -> HashMap<String, String> {
221 HashMap::new()
222 }
223}
224
225impl FromAnyRow for chrono::DateTime<chrono::Utc> {
226 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
227 let mut index = 0;
228 Self::from_any_row_at(row, &mut index)
229 }
230
231 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
232 let res = row.try_get::<String, _>(*index);
233 match res {
234 Ok(s) => {
235 *index += 1;
236 crate::temporal::parse_datetime_utc(&s).map_err(|e| Error::Decode(Box::new(e)))
237 }
238 Err(e) => {
239 if let Ok(i) = row.try_get::<i64, _>(*index) {
241 *index += 1;
242 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)));
243 }
244 Err(Error::Decode(Box::new(e)))
245 }
246 }
247 }
248}
249
250impl<T: AnyImpl> AnyImpl for Option<T> {
255 fn columns() -> Vec<AnyInfo> {
256 T::columns()
257 }
258 fn to_map(&self) -> HashMap<String, String> {
259 match self {
260 Some(v) => v.to_map(),
261 None => HashMap::new(),
262 }
263 }
264}
265
266impl<T: FromAnyRow> FromAnyRow for Option<T> {
267 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
268 match T::from_any_row(row) {
269 Ok(v) => Ok(Some(v)),
270 Err(_) => Ok(None),
271 }
272 }
273
274 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
275 match T::from_any_row_at(row, index) {
276 Ok(v) => Ok(Some(v)),
277 Err(_) => Ok(None),
278 }
279 }
280}
281
282macro_rules! impl_any_tuple {
287 ($($T:ident),+) => {
288 impl<$($T: AnyImpl),+> AnyImpl for ($($T,)+) {
289 fn columns() -> Vec<AnyInfo> {
290 let mut cols = Vec::new();
291 $(
292 cols.extend($T::columns());
293 )+
294 cols
295 }
296
297 fn to_map(&self) -> HashMap<String, String> {
298 let mut map = HashMap::new();
299 #[allow(non_snake_case)]
300 let ($($T,)+) = self;
301 $(
302 map.extend($T.to_map());
303 )+
304 map
305 }
306 }
307
308 impl<$($T: FromAnyRow),+> FromAnyRow for ($($T,)+) {
309 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
310 let mut index = 0;
311 Ok((
312 $(
313 $T::from_any_row_at(row, &mut index)?,
314 )+
315 ))
316 }
317
318 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
319 Ok((
320 $(
321 $T::from_any_row_at(row, index)?,
322 )+
323 ))
324 }
325 }
326 };
327}
328
329impl_any_tuple!(T1);
330impl_any_tuple!(T1, T2);
331impl_any_tuple!(T1, T2, T3);
332impl_any_tuple!(T1, T2, T3, T4);
333impl_any_tuple!(T1, T2, T3, T4, T5);
334impl_any_tuple!(T1, T2, T3, T4, T5, T6);
335impl_any_tuple!(T1, T2, T3, T4, T5, T6, T7);
336impl_any_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);