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 s: String = row.try_get(0).map_err(|e| Error::Decode(Box::new(e)))?;
128 s.parse().map_err(|e| Error::Decode(Box::new(e)))
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 s: String = row.try_get(0).map_err(|e| Error::Decode(Box::new(e)))?;
150 crate::temporal::parse_naive_datetime(&s).map_err(|e| Error::Decode(Box::new(e)))
151 }
152
153 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
154 let s: String = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
155 *index += 1;
156 crate::temporal::parse_naive_datetime(&s).map_err(|e| Error::Decode(Box::new(e)))
157 }
158}
159
160impl AnyImpl for chrono::NaiveDate {
161 fn columns() -> Vec<AnyInfo> {
162 Vec::new()
163 }
164 fn to_map(&self) -> HashMap<String, String> {
165 HashMap::new()
166 }
167}
168
169impl FromAnyRow for chrono::NaiveDate {
170 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
171 let s: String = row.try_get(0).map_err(|e| Error::Decode(Box::new(e)))?;
172 crate::temporal::parse_naive_date(&s).map_err(|e| Error::Decode(Box::new(e)))
173 }
174
175 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
176 let s: String = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
177 *index += 1;
178 crate::temporal::parse_naive_date(&s).map_err(|e| Error::Decode(Box::new(e)))
179 }
180}
181
182impl AnyImpl for chrono::NaiveTime {
183 fn columns() -> Vec<AnyInfo> {
184 Vec::new()
185 }
186 fn to_map(&self) -> HashMap<String, String> {
187 HashMap::new()
188 }
189}
190
191impl FromAnyRow for chrono::NaiveTime {
192 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
193 let s: String = row.try_get(0).map_err(|e| Error::Decode(Box::new(e)))?;
194 crate::temporal::parse_naive_time(&s).map_err(|e| Error::Decode(Box::new(e)))
195 }
196
197 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
198 let s: String = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
199 *index += 1;
200 crate::temporal::parse_naive_time(&s).map_err(|e| Error::Decode(Box::new(e)))
201 }
202}
203
204impl AnyImpl for chrono::DateTime<chrono::Utc> {
205 fn columns() -> Vec<AnyInfo> {
206 Vec::new()
207 }
208 fn to_map(&self) -> HashMap<String, String> {
209 HashMap::new()
210 }
211}
212
213impl FromAnyRow for chrono::DateTime<chrono::Utc> {
214 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
215 let s: String = row.try_get(0).map_err(|e| Error::Decode(Box::new(e)))?;
216 crate::temporal::parse_datetime_utc(&s).map_err(|e| Error::Decode(Box::new(e)))
217 }
218
219 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
220 let s: String = row.try_get(*index).map_err(|e| Error::Decode(Box::new(e)))?;
221 *index += 1;
222 crate::temporal::parse_datetime_utc(&s).map_err(|e| Error::Decode(Box::new(e)))
223 }
224}
225
226impl<T: AnyImpl> AnyImpl for Option<T> {
231 fn columns() -> Vec<AnyInfo> {
232 T::columns()
233 }
234 fn to_map(&self) -> HashMap<String, String> {
235 match self {
236 Some(v) => v.to_map(),
237 None => HashMap::new(),
238 }
239 }
240}
241
242impl<T: FromAnyRow> FromAnyRow for Option<T> {
243 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
244 match T::from_any_row(row) {
245 Ok(v) => Ok(Some(v)),
246 Err(_) => Ok(None),
247 }
248 }
249
250 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
251 match T::from_any_row_at(row, index) {
252 Ok(v) => Ok(Some(v)),
253 Err(_) => Ok(None),
254 }
255 }
256}
257
258macro_rules! impl_any_tuple {
263 ($($T:ident),+) => {
264 impl<$($T: AnyImpl),+> AnyImpl for ($($T,)+) {
265 fn columns() -> Vec<AnyInfo> {
266 let mut cols = Vec::new();
267 $(
268 cols.extend($T::columns());
269 )+
270 cols
271 }
272
273 fn to_map(&self) -> HashMap<String, String> {
274 let mut map = HashMap::new();
275 #[allow(non_snake_case)]
276 let ($($T,)+) = self;
277 $(
278 map.extend($T.to_map());
279 )+
280 map
281 }
282 }
283
284 impl<$($T: FromAnyRow),+> FromAnyRow for ($($T,)+) {
285 fn from_any_row(row: &AnyRow) -> Result<Self, Error> {
286 let mut index = 0;
287 Ok((
288 $(
289 $T::from_any_row_at(row, &mut index)?,
290 )+
291 ))
292 }
293
294 fn from_any_row_at(row: &AnyRow, index: &mut usize) -> Result<Self, Error> {
295 Ok((
296 $(
297 $T::from_any_row_at(row, index)?,
298 )+
299 ))
300 }
301 }
302 };
303}
304
305impl_any_tuple!(T1);
306impl_any_tuple!(T1, T2);
307impl_any_tuple!(T1, T2, T3);
308impl_any_tuple!(T1, T2, T3, T4);
309impl_any_tuple!(T1, T2, T3, T4, T5);
310impl_any_tuple!(T1, T2, T3, T4, T5, T6);
311impl_any_tuple!(T1, T2, T3, T4, T5, T6, T7);
312impl_any_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);