1use super::db_value::{DbValue, DbValueConvertError};
4
5impl TryFrom<DbValue> for i32 {
6 type Error = DbValueConvertError;
7 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
8 match v {
9 DbValue::I32(n) => Ok(n),
10 DbValue::I16(n) => Ok(n as i32),
11 DbValue::I64(n) => n.try_into().map_err(|_| DbValueConvertError {
12 source: DbValue::I64(n),
13 target_type: "i32",
14 }),
15 DbValue::String(s) => s.parse().map_err(|_| DbValueConvertError {
16 source: DbValue::String(s),
17 target_type: "i32",
18 }),
19 other => Err(DbValueConvertError {
20 source: other,
21 target_type: "i32",
22 }),
23 }
24 }
25}
26
27impl TryFrom<DbValue> for i64 {
28 type Error = DbValueConvertError;
29 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
30 match v {
31 DbValue::I64(n) => Ok(n),
32 DbValue::I32(n) => Ok(n as i64),
33 DbValue::I16(n) => Ok(n as i64),
34 DbValue::String(s) => s.parse().map_err(|_| DbValueConvertError {
35 source: DbValue::String(s),
36 target_type: "i64",
37 }),
38 other => Err(DbValueConvertError {
39 source: other,
40 target_type: "i64",
41 }),
42 }
43 }
44}
45
46impl TryFrom<DbValue> for f64 {
47 type Error = DbValueConvertError;
48 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
49 match v {
50 DbValue::F64(x) => Ok(x),
51 DbValue::F32(x) => Ok(x as f64),
52 DbValue::I32(n) => Ok(n as f64),
53 DbValue::I64(n) => Ok(n as f64),
54 DbValue::I16(n) => Ok(n as f64),
55 DbValue::String(s) => s.parse().map_err(|_| DbValueConvertError {
56 source: DbValue::String(s),
57 target_type: "f64",
58 }),
59 other => Err(DbValueConvertError {
60 source: other,
61 target_type: "f64",
62 }),
63 }
64 }
65}
66
67impl TryFrom<DbValue> for f32 {
68 type Error = DbValueConvertError;
69 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
70 match v {
71 DbValue::F32(x) => Ok(x),
72 DbValue::F64(x) => Ok(x as f32),
73 DbValue::I32(n) => Ok(n as f32),
74 DbValue::I64(n) => Ok(n as f32),
75 DbValue::I16(n) => Ok(n as f32),
76 DbValue::String(s) => s.parse().map_err(|_| DbValueConvertError {
77 source: DbValue::String(s),
78 target_type: "f32",
79 }),
80 other => Err(DbValueConvertError {
81 source: other,
82 target_type: "f32",
83 }),
84 }
85 }
86}
87
88impl TryFrom<DbValue> for String {
89 type Error = DbValueConvertError;
90 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
91 match v {
92 DbValue::String(s) => Ok(s),
93 DbValue::Bool(b) => Ok(b.to_string()),
94 DbValue::I16(n) => Ok(n.to_string()),
95 DbValue::I32(n) => Ok(n.to_string()),
96 DbValue::I64(n) => Ok(n.to_string()),
97 DbValue::F32(x) => Ok(x.to_string()),
98 DbValue::F64(x) => Ok(x.to_string()),
99 #[cfg(feature = "chrono")]
100 DbValue::DateTime(dt) => Ok(dt.to_rfc3339()),
101 #[cfg(feature = "chrono")]
102 DbValue::NaiveDateTime(ndt) => Ok(ndt.to_string()),
103 #[cfg(feature = "chrono")]
104 DbValue::NaiveDate(nd) => Ok(nd.to_string()),
105 #[cfg(feature = "uuid")]
106 DbValue::Uuid(u) => Ok(u.to_string()),
107 #[cfg(feature = "decimal")]
108 DbValue::Decimal(d) => Ok(d.to_string()),
109 other => Err(DbValueConvertError {
110 source: other,
111 target_type: "String",
112 }),
113 }
114 }
115}
116
117impl TryFrom<DbValue> for bool {
118 type Error = DbValueConvertError;
119 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
120 match v {
121 DbValue::Bool(b) => Ok(b),
122 DbValue::I64(n) => Ok(n != 0),
123 DbValue::I32(n) => Ok(n != 0),
124 DbValue::I16(n) => Ok(n != 0),
125 DbValue::String(s) => {
126 let lower = s.to_ascii_lowercase();
127 match lower.as_str() {
128 "true" | "t" | "1" => Ok(true),
129 "false" | "f" | "0" => Ok(false),
130 _ => Err(DbValueConvertError {
131 source: DbValue::String(s),
132 target_type: "bool",
133 }),
134 }
135 }
136 other => Err(DbValueConvertError {
137 source: other,
138 target_type: "bool",
139 }),
140 }
141 }
142}
143
144impl TryFrom<DbValue> for Vec<u8> {
145 type Error = DbValueConvertError;
146 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
147 match v {
148 DbValue::Bytes(b) => Ok(b),
149 other => Err(DbValueConvertError {
150 source: other,
151 target_type: "Vec<u8>",
152 }),
153 }
154 }
155}
156
157impl TryFrom<DbValue> for i16 {
158 type Error = DbValueConvertError;
159 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
160 match v {
161 DbValue::I16(n) => Ok(n),
162 DbValue::I32(n) => n.try_into().map_err(|_| DbValueConvertError {
163 source: DbValue::I32(n),
164 target_type: "i16",
165 }),
166 DbValue::I64(n) => n.try_into().map_err(|_| DbValueConvertError {
167 source: DbValue::I64(n),
168 target_type: "i16",
169 }),
170 DbValue::String(s) => s.parse().map_err(|_| DbValueConvertError {
171 source: DbValue::String(s),
172 target_type: "i16",
173 }),
174 other => Err(DbValueConvertError {
175 source: other,
176 target_type: "i16",
177 }),
178 }
179 }
180}
181
182impl TryFrom<DbValue> for i8 {
183 type Error = DbValueConvertError;
184 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
185 match v {
186 DbValue::I16(n) => n.try_into().map_err(|_| DbValueConvertError {
187 source: DbValue::I16(n),
188 target_type: "i8",
189 }),
190 DbValue::I32(n) => n.try_into().map_err(|_| DbValueConvertError {
191 source: DbValue::I32(n),
192 target_type: "i8",
193 }),
194 DbValue::I64(n) => n.try_into().map_err(|_| DbValueConvertError {
195 source: DbValue::I64(n),
196 target_type: "i8",
197 }),
198 DbValue::String(s) => s.parse().map_err(|_| DbValueConvertError {
199 source: DbValue::String(s),
200 target_type: "i8",
201 }),
202 other => Err(DbValueConvertError {
203 source: other,
204 target_type: "i8",
205 }),
206 }
207 }
208}
209
210impl TryFrom<DbValue> for u32 {
211 type Error = DbValueConvertError;
212 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
213 match v {
214 DbValue::I16(n) => (n as i32).try_into().map_err(|_| DbValueConvertError {
215 source: DbValue::I16(n),
216 target_type: "u32",
217 }),
218 DbValue::I32(n) => n.try_into().map_err(|_| DbValueConvertError {
219 source: DbValue::I32(n),
220 target_type: "u32",
221 }),
222 DbValue::I64(n) => n.try_into().map_err(|_| DbValueConvertError {
223 source: DbValue::I64(n),
224 target_type: "u32",
225 }),
226 DbValue::String(s) => s.parse().map_err(|_| DbValueConvertError {
227 source: DbValue::String(s),
228 target_type: "u32",
229 }),
230 other => Err(DbValueConvertError {
231 source: other,
232 target_type: "u32",
233 }),
234 }
235 }
236}
237
238impl TryFrom<DbValue> for u64 {
239 type Error = DbValueConvertError;
240 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
241 match v {
242 DbValue::I16(n) => (n as i64).try_into().map_err(|_| DbValueConvertError {
243 source: DbValue::I16(n),
244 target_type: "u64",
245 }),
246 DbValue::I32(n) => (n as i64).try_into().map_err(|_| DbValueConvertError {
247 source: DbValue::I32(n),
248 target_type: "u64",
249 }),
250 DbValue::I64(n) => n.try_into().map_err(|_| DbValueConvertError {
251 source: DbValue::I64(n),
252 target_type: "u64",
253 }),
254 DbValue::String(s) => s.parse().map_err(|_| DbValueConvertError {
255 source: DbValue::String(s),
256 target_type: "u64",
257 }),
258 other => Err(DbValueConvertError {
259 source: other,
260 target_type: "u64",
261 }),
262 }
263 }
264}
265
266#[cfg(feature = "chrono")]
269impl TryFrom<DbValue> for chrono::DateTime<chrono::Utc> {
270 type Error = DbValueConvertError;
271 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
272 match v {
273 DbValue::DateTime(dt) => Ok(dt),
274 DbValue::String(s) => chrono::DateTime::parse_from_rfc3339(&s)
275 .map(|dt| dt.with_timezone(&chrono::Utc))
276 .map_err(|_| DbValueConvertError {
277 source: DbValue::String(s),
278 target_type: "DateTime<Utc>",
279 }),
280 other => Err(DbValueConvertError {
281 source: other,
282 target_type: "DateTime<Utc>",
283 }),
284 }
285 }
286}
287
288#[cfg(feature = "chrono")]
289impl TryFrom<DbValue> for chrono::NaiveDateTime {
290 type Error = DbValueConvertError;
291 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
292 match v {
293 DbValue::NaiveDateTime(ndt) => Ok(ndt),
294 DbValue::String(s) => {
295 chrono::NaiveDateTime::parse_from_str(&s, "%Y-%m-%d %H:%M:%S")
296 .or_else(|_| {
297 chrono::NaiveDateTime::parse_from_str(&s, "%Y-%m-%dT%H:%M:%S")
299 })
300 .map_err(|_| DbValueConvertError {
301 source: DbValue::String(s),
302 target_type: "NaiveDateTime",
303 })
304 }
305 other => Err(DbValueConvertError {
306 source: other,
307 target_type: "NaiveDateTime",
308 }),
309 }
310 }
311}
312
313#[cfg(feature = "chrono")]
314impl TryFrom<DbValue> for chrono::NaiveDate {
315 type Error = DbValueConvertError;
316 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
317 match v {
318 DbValue::NaiveDate(nd) => Ok(nd),
319 DbValue::String(s) => {
320 chrono::NaiveDate::parse_from_str(&s, "%Y-%m-%d").map_err(|_| DbValueConvertError {
321 source: DbValue::String(s),
322 target_type: "NaiveDate",
323 })
324 }
325 other => Err(DbValueConvertError {
326 source: other,
327 target_type: "NaiveDate",
328 }),
329 }
330 }
331}
332
333#[cfg(feature = "uuid")]
334impl TryFrom<DbValue> for uuid::Uuid {
335 type Error = DbValueConvertError;
336 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
337 match v {
338 DbValue::Uuid(u) => Ok(u),
339 DbValue::String(s) => uuid::Uuid::parse_str(&s).map_err(|_| DbValueConvertError {
340 source: DbValue::String(s),
341 target_type: "Uuid",
342 }),
343 other => Err(DbValueConvertError {
344 source: other,
345 target_type: "Uuid",
346 }),
347 }
348 }
349}
350
351#[cfg(feature = "decimal")]
352impl TryFrom<DbValue> for rust_decimal::Decimal {
353 type Error = DbValueConvertError;
354 fn try_from(v: DbValue) -> Result<Self, Self::Error> {
355 match v {
356 DbValue::Decimal(d) => Ok(d),
357 DbValue::String(s) => s.parse().map_err(|_| DbValueConvertError {
358 source: DbValue::String(s),
359 target_type: "Decimal",
360 }),
361 DbValue::I32(n) => Ok(rust_decimal::Decimal::from(n)),
362 DbValue::I64(n) => Ok(rust_decimal::Decimal::from(n)),
363 other => Err(DbValueConvertError {
364 source: other,
365 target_type: "Decimal",
366 }),
367 }
368 }
369}