Skip to main content

tank_core/
as_value.rs

1#![allow(unused_imports)]
2use crate::{
3    Error, FixedDecimal, Interval, Result, Value, consume_while, extract_number, truncate_long,
4};
5use crate::{month_to_number, number_to_month};
6use anyhow::{Context, anyhow};
7#[cfg(feature = "chrono")]
8use chrono::{Datelike, Offset, Timelike};
9use rust_decimal::{Decimal, prelude::FromPrimitive, prelude::ToPrimitive};
10use std::{
11    any,
12    borrow::Cow,
13    cell::{Cell, RefCell},
14    collections::{BTreeMap, HashMap, LinkedList, VecDeque},
15    hash::Hash,
16    num::{
17        NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize, NonZeroU8,
18        NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize,
19    },
20    rc::Rc,
21    sync::{Arc, RwLock},
22};
23use time::{PrimitiveDateTime, UtcDateTime, format_description::parse_borrowed};
24use uuid::Uuid;
25
26/// Bidirectional conversion between Rust types and `Value`.
27pub trait AsValue {
28    /// Return NULL variant.
29    fn as_empty_value() -> Value;
30    /// Convert to `Value`.
31    fn as_value(self) -> Value;
32    /// Convert from `Value`.
33    fn try_from_value(value: Value) -> Result<Self>
34    where
35        Self: Sized;
36    /// Parse string.
37    fn parse(input: impl AsRef<str>) -> Result<Self>
38    where
39        Self: Sized,
40    {
41        Err(anyhow!(
42            "Cannot parse '{}' as {} (the parse method is not implemented)",
43            truncate_long!(input.as_ref()),
44            any::type_name::<Self>()
45        ))
46    }
47}
48
49impl AsValue for Value {
50    fn as_empty_value() -> Value {
51        Value::Null
52    }
53    fn as_value(self) -> Value {
54        self
55    }
56    fn try_from_value(value: Value) -> Result<Self>
57    where
58        Self: Sized,
59    {
60        Ok(value)
61    }
62}
63
64impl From<&'static str> for Value {
65    fn from(value: &'static str) -> Self {
66        Value::Varchar(Some(value.into()))
67    }
68}
69
70macro_rules! impl_as_value {
71    ($source:ty, $destination:path $(, $pat_rest:pat => $expr_rest:expr)* $(,)?) => {
72        impl AsValue for $source {
73            fn as_empty_value() -> Value {
74                $destination(None)
75            }
76            fn as_value(self) -> Value {
77                $destination(Some(self as _))
78            }
79            fn try_from_value(value: Value) -> Result<Self> {
80                match value {
81                    $destination(Some(v), ..) => Ok(v as _),
82                    $($pat_rest => $expr_rest,)*
83                    #[allow(unreachable_patterns)]
84                    Value::Int8(Some(v), ..) => {
85                        let mut max = <$source>::MAX as i128;
86                        if max < 0 {
87                            max = i128::MAX;
88                        }
89                        if (v as i128).clamp(<$source>::MIN as _, max) != v as i128 {
90                            return Err(anyhow!(
91                                "Value {v}: i8 is out of range for {}",
92                                any::type_name::<Self>(),
93                            ));
94                        }
95                        Ok(v as $source)
96                    }
97                    #[allow(unreachable_patterns)]
98                    Value::Int16(Some(v), ..) => {
99                        let mut max = <$source>::MAX as i128;
100                        if max < 0 {
101                            max = i128::MAX;
102                        }
103                        if (v as i128).clamp(<$source>::MIN as _, max) != v as i128 {
104                            return Err(anyhow!(
105                                "Value {v}: i16 is out of range for {}",
106                                any::type_name::<Self>(),
107                            ));
108                        }
109                        Ok(v as $source)
110                    }
111                    #[allow(unreachable_patterns)]
112                    Value::Int32(Some(v), ..) => {
113                        let mut max = <$source>::MAX as i128;
114                        if max < 0 {
115                            max = i128::MAX;
116                        }
117                        if (v as i128).clamp(<$source>::MIN as _, max as _) != v as i128 {
118                            return Err(anyhow!(
119                                "Value {v}: i32 is out of range for {}",
120                                any::type_name::<Self>(),
121                            ));
122                        }
123                        Ok(v as $source)
124                    }
125                    #[allow(unreachable_patterns)]
126                    // SQL INTEGER becomes i64
127                    Value::Int64(Some(v), ..) => {
128                        let mut max = <$source>::MAX as i128;
129                        if max < 0 {
130                            max = i128::MAX;
131                        }
132                        if (v as i128).clamp(<$source>::MIN as _, max) != v as i128 {
133                            return Err(anyhow!(
134                                "Value {v}: i64 is out of range for {}",
135                                any::type_name::<Self>(),
136                            ));
137                        }
138                        Ok(v as $source)
139                    }
140                    #[allow(unreachable_patterns)]
141                    // SQL VARINT becomes i128
142                    Value::Int128(Some(v), ..) => {
143                        let mut max = <$source>::MAX as i128;
144                        if max < 0 {
145                            max = i128::MAX;
146                        }
147                        if v.clamp(<$source>::MIN as _, max) != v as i128 {
148                            return Err(anyhow!(
149                                "Value {v}: i128 is out of range for {}",
150                                any::type_name::<Self>(),
151                            ));
152                        }
153                        Ok(v as _)
154                    },
155                    #[allow(unreachable_patterns)]
156                    Value::UInt8(Some(v), ..) => {
157                        let mut max = <$source>::MAX as i128;
158                        if max < 0 {
159                            max = i128::MAX;
160                        }
161                        if (v as i128).clamp(<$source>::MIN as _, max) != v as i128 {
162                            return Err(anyhow!(
163                                "Value {v}: u8 is out of range for {}",
164                                any::type_name::<Self>(),
165                            ));
166                        }
167                        Ok(v as $source)
168                    }
169                    #[allow(unreachable_patterns)]
170                    Value::UInt16(Some(v), ..) => {
171                        let mut max = <$source>::MAX as i128;
172                        if max < 0 {
173                            max = i128::MAX;
174                        }
175                        if (v as i128).clamp(<$source>::MIN as _, max) != v as i128 {
176                            return Err(anyhow!(
177                                "Value {v}: u16 is out of range for {}",
178                                any::type_name::<Self>(),
179                            ));
180                        }
181                        Ok(v as $source)
182                    }
183                    #[allow(unreachable_patterns)]
184                    Value::UInt32(Some(v), ..) => {
185                        let mut max = <$source>::MAX as i128;
186                        if max < 0 {
187                            max = i128::MAX;
188                        }
189                        if (v as i128).clamp(<$source>::MIN as _, max) != v as i128 {
190                            return Err(anyhow!(
191                                "Value {v}: u32 is out of range for {}",
192                                any::type_name::<Self>(),
193                            ));
194                        }
195                        Ok(v as $source)
196                    }
197                    #[allow(unreachable_patterns)]
198                    Value::UInt64(Some(v), ..) => {
199                        let mut max = <$source>::MAX as i128;
200                        if max < 0 {
201                            max = i128::MAX;
202                        }
203                        if (v as i128).clamp(<$source>::MIN as _, max) != v as i128 {
204                            return Err(anyhow!(
205                                "Value {v}: u64 is out of range for {}",
206                                any::type_name::<Self>(),
207                            ));
208                        }
209                        Ok(v as $source)
210                    }
211                    #[allow(unreachable_patterns)]
212                    Value::UInt128(Some(v), ..) => {
213                        let mut max = <$source>::MAX as i128;
214                        if max < 0 {
215                            max = i128::MAX;
216                        }
217                        // u128 may exceed i128::MAX; guard against wrapping before clamping.
218                        let v128 = if v > i128::MAX as u128 {
219                            i128::MAX
220                        } else {
221                            v as i128
222                        };
223                        if v128.clamp(<$source>::MIN as _, max) != v128 {
224                            return Err(anyhow!(
225                                "Value {v}: u128 is out of range for {}",
226                                any::type_name::<Self>(),
227                            ));
228                        }
229                        Ok(v as $source)
230                    }
231                    #[allow(unreachable_patterns)]
232                    // SQL Generic floating point value
233                    Value::Float64(Some(v), ..) => {
234                        if v.is_finite() && v.fract() == 0.0 {
235                            let min = <$source>::MIN as f64;
236                            let max_exclusive = <$source>::MAX as f64 + 1.0;
237                            if v >= min && v < max_exclusive {
238                                return Ok(v as $source);
239                            }
240                        }
241                        Err(anyhow!(
242                            "Value {v}: f64 does not fit into {}",
243                            any::type_name::<Self>(),
244                        ))
245                    },
246                    #[allow(unreachable_patterns)]
247                    Value::Float32(Some(v), ..) => {
248                        Self::try_from_value(Value::Float64(Some(v as f64)))
249                    }
250                    // This is needed to allow integer keys in maps, in some drivers the maps keys are strings only
251                    Value::Varchar(Some(ref v), ..) => <Self as AsValue>::parse(v).with_context(|| {
252                        format!("While parsing a {} from `{}`", any::type_name::<Self>(), v)
253                    }),
254                    Value::Json(Some(serde_json::Value::Number(v)), ..) => {
255                        let integer = v.as_i128().or_else(|| {
256                            let f = v.as_f64()?;
257                            let max_exclusive = i128::MAX as f64 + 1.0;
258                            if f.fract() == 0.0 && f >= i128::MIN as f64 && f < max_exclusive {
259                                Some(f as i128)
260                            } else {
261                                None
262                            }
263                        });
264                        let mut max = <$source>::MAX as i128;
265                        if max < 0 {
266                            max = i128::MAX;
267                        }
268                        if let Some(v) = integer
269                            && v.clamp(<$source>::MIN as _, max) == v as i128 {
270                            return Ok(v as $source);
271                        }
272                        Err(anyhow!(
273                            "Value {v} from json number is out of range for {} (extracted integer is: {integer:?})",
274                            any::type_name::<Self>(),
275                        ))
276                    }
277                    // This is needed to allow integer keys in maps, in some drivers the maps are json objects
278                    Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
279                    Value::Unknown(Some(ref v), ..) => Self::parse(v).with_context(|| {
280                        format!("While parsing a {} from `{}`", any::type_name::<Self>(), v)
281                    }),
282                    _ => Err(anyhow!(
283                        "Cannot convert {value:?} to {}",
284                        any::type_name::<Self>(),
285                    )),
286                }
287            }
288            fn parse(input: impl AsRef<str>) -> Result<Self> {
289                input.as_ref().parse::<Self>().map_err(Into::into)
290            }
291        }
292    };
293}
294
295impl_as_value!(
296    i8,
297    Value::Int8,
298    Value::Int16(Some(v), ..) => {
299        let result = v as i8;
300        if result as i16 != v {
301            return Err(anyhow!("Value {v}: i16 is out of range for i8"));
302        }
303        Ok(result)
304    },
305);
306
307impl_as_value!(
308    i16,
309    Value::Int16,
310    Value::Int8(Some(v), ..) => Ok(v as _),
311    Value::UInt16(Some(v), ..) => {
312        i16::try_from(v).map_err(|_| anyhow!("Value {v}: u16 is out of range for i16"))
313    },
314    Value::UInt8(Some(v), ..) => Ok(v as _),
315);
316
317impl_as_value!(
318    i32,
319    Value::Int32,
320    Value::Int16(Some(v), ..) => Ok(v as _),
321    Value::Int8(Some(v), ..) => Ok(v as _),
322    Value::UInt32(Some(v), ..) => {
323        i32::try_from(v).map_err(|_| anyhow!("Value {v}: u32 is out of range for i32"))
324    },
325    Value::UInt16(Some(v), ..) => Ok(v as _),
326    Value::UInt8(Some(v), ..) => Ok(v as _),
327    Value::Decimal(Some(v), ..) => {
328        let make_error = || anyhow!("Value {v}: Decimal does not fit into i32");
329        if !v.is_integer() {
330            return Err(make_error().context("The value is not an integer"));
331        }
332        v.to_i32().ok_or_else(make_error)
333    }
334);
335
336impl_as_value!(
337    i64,
338    Value::Int64,
339    Value::Int32(Some(v), ..) => Ok(v as _),
340    Value::Int16(Some(v), ..) => Ok(v as _),
341    Value::Int8(Some(v), ..) => Ok(v as _),
342    Value::UInt64(Some(v), ..) => {
343        i64::try_from(v).map_err(|_| anyhow!("Value {v}: u64 is out of range for i64"))
344    },
345    Value::UInt32(Some(v), ..) => Ok(v as _),
346    Value::UInt16(Some(v), ..) => Ok(v as _),
347    Value::UInt8(Some(v), ..) => Ok(v as _),
348    Value::Decimal(Some(v), ..) => {
349        let make_error = || anyhow!("Value {v}: Decimal does not fit into i64");
350        if !v.is_integer() {
351            return Err(make_error().context("The value is not an integer"));
352        }
353        v.to_i64().ok_or_else(make_error)
354    }
355);
356
357impl_as_value!(
358    i128,
359    Value::Int128,
360    Value::Int64(Some(v), ..) => Ok(v as _),
361    Value::Int32(Some(v), ..) => Ok(v as _),
362    Value::Int16(Some(v), ..) => Ok(v as _),
363    Value::Int8(Some(v), ..) => Ok(v as _),
364    Value::UInt128(Some(v), ..) => {
365        i128::try_from(v).map_err(|_| anyhow!("Value {v}: u128 is out of range for i128"))
366    },
367    Value::UInt64(Some(v), ..) => Ok(v as _),
368    Value::UInt32(Some(v), ..) => Ok(v as _),
369    Value::UInt16(Some(v), ..) => Ok(v as _),
370    Value::UInt8(Some(v), ..) => Ok(v as _),
371    Value::Decimal(Some(v), ..) => {
372        let make_error = || anyhow!("Value {v}: Decimal does not fit into i128");
373        if !v.is_integer() {
374            return Err(make_error().context("The value is not an integer"));
375        }
376        v.to_i128().ok_or_else(make_error)
377    }
378);
379
380impl_as_value!(
381    isize,
382    Value::Int64,
383    Value::Int32(Some(v), ..) => Ok(v as _),
384    Value::Int16(Some(v), ..) => Ok(v as _),
385    Value::Int8(Some(v), ..) => Ok(v as _),
386    Value::UInt64(Some(v), ..) => {
387        isize::try_from(v).map_err(|_| anyhow!("Value {v}: u64 is out of range for isize"))
388    },
389    Value::Decimal(Some(v), ..) => {
390        let make_error = || anyhow!("Value {v}: Decimal does not fit into i64");
391        if !v.is_integer() {
392            return Err(make_error().context("The value is not an integer"));
393        }
394        v.to_isize().ok_or_else(make_error)
395    }
396);
397
398impl_as_value!(
399    u8,
400    Value::UInt8,
401    Value::Int16(Some(v), ..) => {
402        v.to_u8().ok_or_else(|| anyhow!("Value {v}: i16 is out of range for u8"))
403    }
404);
405
406impl_as_value!(
407    u16,
408    Value::UInt16,
409    Value::UInt8(Some(v), ..) => Ok(v as _),
410    Value::Int32(Some(v), ..) => {
411        let result = v as u16;
412        if result as i32 != v {
413            return Err(anyhow!("Value {v}: i32 is out of range for u16"));
414        }
415        Ok(result)
416    }
417);
418
419impl_as_value!(
420    u32,
421    Value::UInt32,
422    Value::UInt16(Some(v), ..) => Ok(v as _),
423    Value::UInt8(Some(v), ..) => Ok(v as _),
424);
425
426impl_as_value!(
427    u64,
428    Value::UInt64,
429    Value::UInt32(Some(v), ..) => Ok(v as _),
430    Value::UInt16(Some(v), ..) => Ok(v as _),
431    Value::UInt8(Some(v), ..) => Ok(v as _),
432    Value::Decimal(Some(v), ..) => {
433        let make_error = || anyhow!("Value {v}: Decimal does not fit into u64");
434        if !v.is_integer() {
435            return Err(make_error().context("The value is not an integer"));
436        }
437        v.to_u64().ok_or_else(make_error)
438    }
439);
440
441impl_as_value!(
442    u128,
443    Value::UInt128,
444    Value::UInt64(Some(v), ..) => Ok(v as _),
445    Value::UInt32(Some(v), ..) => Ok(v as _),
446    Value::UInt16(Some(v), ..) => Ok(v as _),
447    Value::UInt8(Some(v), ..) => Ok(v as _),
448    Value::Decimal(Some(v), ..) => {
449        let make_error = || anyhow!("Value {v}: Decimal does not fit into u128");
450        if !v.is_integer() {
451            return Err(make_error().context("The value is not an integer"));
452        }
453        v.to_u128().ok_or_else(make_error)
454    }
455);
456
457impl_as_value!(
458    usize,
459    Value::UInt64,
460    Value::UInt32(Some(v), ..) => Ok(v as _),
461    Value::UInt16(Some(v), ..) => Ok(v as _),
462    Value::UInt8(Some(v), ..) => Ok(v as _),
463    Value::Decimal(Some(v), ..) => {
464        let make_error = || anyhow!("Value {v}: Decimal does not fit into usize");
465        if !v.is_integer() {
466            return Err(make_error().context("The value is not an integer"));
467        }
468        v.to_usize().ok_or_else(make_error)
469    }
470);
471
472macro_rules! impl_as_value {
473    ($source:ty, $helper:path) => {
474        impl AsValue for $source {
475            fn as_empty_value() -> Value {
476                <$helper as AsValue>::as_empty_value()
477            }
478            fn as_value(self) -> Value {
479                AsValue::as_value(Into::<$helper>::into(self))
480            }
481            fn try_from_value(value: Value) -> Result<Self>
482            where
483                Self: Sized,
484            {
485                Ok(<$helper as AsValue>::try_from_value(value)?.try_into()?)
486            }
487        }
488    };
489}
490
491impl_as_value!(NonZeroI8, i8);
492impl_as_value!(NonZeroI16, i16);
493impl_as_value!(NonZeroI32, i32);
494impl_as_value!(NonZeroI64, i64);
495impl_as_value!(NonZeroI128, i128);
496impl_as_value!(NonZeroIsize, isize);
497impl_as_value!(NonZeroU8, u8);
498impl_as_value!(NonZeroU16, u16);
499impl_as_value!(NonZeroU32, u32);
500impl_as_value!(NonZeroU64, u64);
501impl_as_value!(NonZeroU128, u128);
502impl_as_value!(NonZeroUsize, usize);
503
504macro_rules! impl_as_value {
505    ($source:ty, $destination:path, $extract:expr $(, $pat_rest:pat => $expr_rest:expr)* $(,)?) => {
506        impl AsValue for $source {
507            fn as_empty_value() -> Value {
508                $destination(None)
509            }
510            fn as_value(self) -> Value {
511                $destination(Some(self.into()))
512            }
513            fn try_from_value(value: Value) -> Result<Self> {
514                match value {
515                    $destination(Some(v), ..) => Ok(v.into()),
516                    $($pat_rest => $expr_rest,)*
517                    #[allow(unreachable_patterns)]
518                    Value::Varchar(Some(ref v), ..) => {
519                        <Self as AsValue>::parse(v).with_context(|| {
520                            format!("While parsing a {} from `{}`", any::type_name::<Self>(), v)
521                        })
522                    }
523                    Value::Unknown(Some(ref v), ..) => {
524                        <Self as AsValue>::parse(v).with_context(|| {
525                            format!("While parsing a {} from `{}`", any::type_name::<Self>(), v)
526                        })
527                    }
528                    _ => Err(anyhow!(
529                        "Cannot convert {value:?} to {}",
530                        any::type_name::<Self>(),
531                    )),
532                }
533            }
534            fn parse(input: impl AsRef<str>) -> Result<Self> {
535                $extract(input.as_ref())
536            }
537        }
538    };
539}
540
541impl_as_value!(
542    bool,
543    Value::Boolean,
544    |input: &str| {
545        match input {
546            x if x.eq_ignore_ascii_case("true") || x.eq_ignore_ascii_case("t") || x.eq("1") => Ok(true),
547            x if x.eq_ignore_ascii_case("false") || x.eq_ignore_ascii_case("f") || x.eq("0") => Ok(false),
548            _  => return Err(anyhow!("Cannot parse boolean from `{input}`"))
549        }
550    },
551    Value::Int8(Some(v), ..) => Ok(v != 0),
552    Value::Int16(Some(v), ..) => Ok(v != 0),
553    Value::Int32(Some(v), ..) => Ok(v != 0),
554    Value::Int64(Some(v), ..) => Ok(v != 0),
555    Value::Int128(Some(v), ..) => Ok(v != 0),
556    Value::UInt8(Some(v), ..) => Ok(v != 0),
557    Value::UInt16(Some(v), ..) => Ok(v != 0),
558    Value::UInt32(Some(v), ..) => Ok(v != 0),
559    Value::UInt64(Some(v), ..) => Ok(v != 0),
560    Value::UInt128(Some(v), ..) => Ok(v != 0),
561    Value::Json(Some(serde_json::Value::Bool(v)), ..) => Ok(v),
562    Value::Json(Some(serde_json::Value::Number(v)), ..) => {
563        let n = v.as_i64();
564        if n == Some(0) {
565            Ok(false)
566        } else if n == Some(1) {
567            Ok(true)
568        } else {
569            Err(anyhow!("Cannot convert json number `{v:?}` to bool"))
570        }
571    },
572);
573
574impl_as_value!(
575    f32,
576    Value::Float32,
577    |input: &str| Ok(input.parse::<f32>()?),
578    Value::Float64(Some(v), ..) => Ok(v as _),
579    Value::Decimal(Some(v), ..) => Ok(v.try_into()?),
580    Value::Json(Some(serde_json::Value::Number(v)), ..) => {
581        let Some(v) = v.as_f64() else {
582            return Err(anyhow!("Cannot convert json number `{v:?}` to f32"));
583        };
584        Ok(v as _)
585    }
586);
587
588impl_as_value!(
589    f64,
590    Value::Float64,
591    |input: &str| Ok(input.parse::<f64>()?),
592    Value::Float32(Some(v), ..) => Ok(v as _),
593    Value::Decimal(Some(v), ..) => Ok(v.try_into()?),
594    Value::Json(Some(serde_json::Value::Number(v)), ..) => {
595        let Some(v) = v.as_f64() else {
596            return Err(anyhow!("Cannot convert json number `{v:?}` to f64"));
597        };
598        Ok(v)
599    }
600);
601
602impl_as_value!(
603    char,
604    Value::Char,
605    |input: &str| {
606        if input.chars().count() != 1 {
607            return Err(anyhow!("Cannot convert `{input:?}` to char"))
608        }
609        Ok(input.chars().next().expect("Should have one character"))
610    },
611    Value::Varchar(Some(v), ..) => {
612        if v.chars().count() != 1 {
613            return Err(anyhow!(
614                "Cannot convert varchar `{}` to char because it has more than one character",
615                truncate_long!(v)
616            ))
617        }
618        Ok(v.chars().next().unwrap())
619    },
620    Value::Json(Some(serde_json::Value::String(v)), ..) => {
621        if v.chars().count() != 1 {
622            return Err(anyhow!(
623                "Cannot convert json `{}` to char because it has more than one character",
624                truncate_long!(v)
625            ))
626        }
627        Ok(v.chars().next().unwrap())
628    },
629    value @ (
630        Value::Int8(Some(..), ..)
631        | Value::Int16(Some(..), ..)
632        | Value::Int32(Some(..), ..)
633        | Value::Int64(Some(..), ..)
634        | Value::Int128(Some(..), ..)
635        | Value::UInt8(Some(..), ..)
636        | Value::UInt16(Some(..), ..)
637        | Value::UInt32(Some(..), ..)
638        | Value::UInt64(Some(..), ..)
639        | Value::UInt128(Some(..), ..)
640    ) => {
641        let code = u32::try_from_value(value.clone()).map_err(|_| {
642            anyhow!("Cannot convert {value:?} to char because it is not a valid unicode scalar value")
643        })?;
644        char::from_u32(code).ok_or_else(|| {
645            anyhow!("Cannot convert {value:?} to char because it is not a valid unicode scalar value")
646        })
647    }
648);
649
650impl_as_value!(
651    String,
652    Value::Varchar,
653    |input: &str| {
654        Ok(input.into())
655    },
656    v @ (
657        Value::Int8(Some(..), ..)
658        | Value::Int16(Some(..), ..)
659        | Value::Int32(Some(..), ..)
660        | Value::Int64(Some(..), ..)
661        | Value::Int128(Some(..), ..)
662        | Value::UInt8(Some(..), ..)
663        | Value::UInt16(Some(..), ..)
664        | Value::UInt32(Some(..), ..)
665        | Value::UInt64(Some(..), ..)
666        | Value::UInt128(Some(..), ..)
667        | Value::Float32(Some(..), ..)
668        | Value::Float64(Some(..), ..)
669        | Value::Decimal(Some(..), ..)
670        | Value::Char(Some(..), ..)
671        | Value::Date(Some(..), ..)
672        | Value::Time(Some(..), ..)
673        | Value::Timestamp(Some(..), ..)
674        | Value::TimestampWithTimezone(Some(..), ..)
675        | Value::Uuid(Some(..), ..)
676    ) => Ok(v.to_string()),
677    Value::Json(Some(serde_json::Value::String(v)), ..) => Ok(v),
678);
679
680impl_as_value!(Box<[u8]>, Value::Blob, |mut input: &str| {
681    if input.starts_with("\\x") {
682        input = &input[2..];
683    }
684    let filter_x = input.contains('x');
685    let result = if filter_x {
686        hex::decode(input.chars().filter(|c| *c != 'x').collect::<String>())
687    } else {
688        hex::decode(input)
689    }
690    .map(Into::into)
691    .context(format!(
692        "While decoding `{}` as {}",
693        truncate_long!(input),
694        any::type_name::<Self>()
695    ))?;
696    Ok(result)
697});
698
699impl_as_value!(
700    Interval,
701    Value::Interval,
702    |mut input: &str| {
703        let make_context = || {
704            anyhow!(
705                "Cannot parse interval from `{}`",
706                truncate_long!(input)
707            )
708        };
709        match input.chars().peekable().peek() {
710            Some(v) if *v == '"' || *v == '\'' => {
711                input = &input[1..];
712                if !input.ends_with(*v) {
713                    return Err(make_context());
714                }
715                input = input.trim_end_matches(*v);
716            }
717            _ => {}
718        };
719        let mut interval = Interval::ZERO;
720        loop {
721            let mut cur = input;
722            let Ok(count) = extract_number::<true>(&mut cur).parse::<i128>() else {
723                break;
724            };
725            cur = cur.trim_start();
726            let unit = consume_while(&mut cur, char::is_ascii_alphabetic);
727            if unit.is_empty() {
728                break;
729            }
730            match unit {
731                x if x.eq_ignore_ascii_case("y")
732                    || x.eq_ignore_ascii_case("year")
733                    || x.eq_ignore_ascii_case("years") =>
734                {
735                    interval += Interval::from_years(count as _)
736                }
737                x if x.eq_ignore_ascii_case("mon")
738                    || x.eq_ignore_ascii_case("mons")
739                    || x.eq_ignore_ascii_case("month")
740                    || x.eq_ignore_ascii_case("months") =>
741                {
742                    interval += Interval::from_months(count as _)
743                }
744                x if x.eq_ignore_ascii_case("d")
745                    || x.eq_ignore_ascii_case("day")
746                    || x.eq_ignore_ascii_case("days") =>
747                {
748                    interval += Interval::from_days(count as _)
749                }
750                x if x.eq_ignore_ascii_case("h")
751                    || x.eq_ignore_ascii_case("hour")
752                    || x.eq_ignore_ascii_case("hours") =>
753                {
754                    interval += Interval::from_hours(count as _)
755                }
756                x if x.eq_ignore_ascii_case("min")
757                    || x.eq_ignore_ascii_case("mins")
758                    || x.eq_ignore_ascii_case("minute")
759                    || x.eq_ignore_ascii_case("minutes") =>
760                {
761                    interval += Interval::from_mins(count as _)
762                }
763                x if x.eq_ignore_ascii_case("s")
764                    || x.eq_ignore_ascii_case("sec")
765                    || x.eq_ignore_ascii_case("secs")
766                    || x.eq_ignore_ascii_case("second")
767                    || x.eq_ignore_ascii_case("seconds") =>
768                {
769                    interval += Interval::from_secs(count as _)
770                }
771                x if x.eq_ignore_ascii_case("micro")
772                    || x.eq_ignore_ascii_case("micros")
773                    || x.eq_ignore_ascii_case("microsecond")
774                    || x.eq_ignore_ascii_case("microseconds") =>
775                {
776                    interval += Interval::from_micros(count as _)
777                }
778                x if x.eq_ignore_ascii_case("ns")
779                    || x.eq_ignore_ascii_case("nano")
780                    || x.eq_ignore_ascii_case("nanos")
781                    || x.eq_ignore_ascii_case("nanosecond")
782                    || x.eq_ignore_ascii_case("nanoseconds") =>
783                {
784                    interval += Interval::from_nanos(count as _)
785                }
786                _ => return Err(make_context()),
787            }
788            input = cur.trim_start();
789        }
790        let neg = if Some('-') == input.chars().next() {
791            input = input[1..].trim_ascii_start();
792            true
793        } else {
794            false
795        };
796        let mut time_interval = Interval::ZERO;
797        let num = extract_number::<true>(&mut input);
798        if !num.is_empty() {
799            let num = num.parse::<u64>().with_context(make_context)?;
800            time_interval += Interval::from_hours(num as _);
801            if Some(':') == input.chars().next() {
802                input = &input[1..];
803                let num = extract_number::<false>(&mut input).parse::<u64>()?;
804                if input.is_empty() {
805                    return Err(make_context());
806                }
807                time_interval += Interval::from_mins(num as _);
808                if Some(':') == input.chars().next() {
809                    input = &input[1..];
810                    let num = extract_number::<false>(&mut input)
811                        .parse::<u64>()
812                        .with_context(make_context)?;
813                    time_interval += Interval::from_secs(num as _);
814                    if Some('.') == input.chars().next() {
815                        input = &input[1..];
816                        let fraction = extract_number::<false>(&mut input);
817                        if fraction.is_empty() || fraction.len() > 9 {
818                            return Err(anyhow!("Sub-nanosecond precision cannot be represented")).with_context(make_context);
819                        }
820                        let nanos = fraction
821                            .parse::<i128>()
822                            .with_context(make_context)?
823                            .saturating_mul(10_i128.pow((9 - fraction.len()) as u32));
824                        time_interval += Interval::from_nanos(nanos);
825                    }
826                }
827            }
828            if neg {
829                interval -= time_interval;
830            } else {
831                interval += time_interval;
832            }
833        }
834        if !input.is_empty() {
835            return Err(make_context());
836        }
837        Ok(interval)
838    },
839    Value::Varchar(Some(ref v), ..) => <Self as AsValue>::parse(v),
840    Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
841);
842
843impl_as_value!(
844    std::time::Duration,
845    Value::Interval,
846    |v| <Interval as AsValue>::parse(v).map(Into::into),
847    Value::Varchar(Some(ref v), ..) => <Self as AsValue>::parse(v),
848    Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
849);
850
851impl_as_value!(
852    time::Duration,
853    Value::Interval,
854    |v| <Interval as AsValue>::parse(v).map(Into::into),
855    Value::Varchar(Some(ref v), ..) => <Self as AsValue>::parse(v),
856    Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
857);
858
859impl_as_value!(
860    Uuid,
861    Value::Uuid,
862    |input: &str| {
863        let uuid = Uuid::parse_str(input).with_context(|| {
864            format!(
865                "Cannot parse a uuid value from `{}`",
866                truncate_long!(input)
867            )
868        })?;
869        Ok(uuid)
870    },
871    Value::Varchar(Some(v), ..) => <Self as AsValue>::parse(v),
872    Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
873);
874
875/// Parses `$value` against each of the given formats, returning the first
876/// successful parse and advancing `$value` past the consumed input.
877///
878/// Yields `None` when no format matches, and deliberately never builds an `anyhow::Error`.
879macro_rules! parse_time {
880    ($value: ident, $($formats:literal),+ $(,)?) => {
881        'value: {
882            for format in [$($formats,)+] {
883                let Ok(format) = parse_borrowed::<2>(format) else {
884                    break 'value None;
885                };
886                let mut parsed = time::parsing::Parsed::new();
887                let remaining = parsed.parse_items($value.as_bytes(), &format);
888                if let Ok(remaining) = remaining {
889                    if let Ok(result) = parsed.try_into() {
890                        $value = &$value[($value.len() - remaining.len())..];
891                        break 'value Some(result);
892                    }
893                }
894            }
895            None
896        }
897    }
898}
899
900impl_as_value!(
901    time::Date,
902    Value::Date,
903    |input: &str| {
904        let mut value = input;
905        let mut result: time::Date = parse_time!(value, "[year]-[month]-[day]")
906            .ok_or_else(|| anyhow!("Cannot parse `{}` as time::Date", truncate_long!(input)))?;
907        {
908            let mut attempt = value.trim_start();
909            let suffix = consume_while(&mut attempt, char::is_ascii_alphabetic);
910            if suffix.eq_ignore_ascii_case("bc") {
911                result =
912                    time::Date::from_calendar_date(-(result.year() - 1), result.month(), result.day())?;
913                value = attempt;
914            }
915            if suffix.eq_ignore_ascii_case("ad") {
916                value = attempt
917            }
918        }
919        if !value.is_empty() {
920            return Err(anyhow!("Cannot parse `{}` as time::Date", truncate_long!(input)))
921        }
922        Ok(result)
923    },
924    Value::Varchar(Some(v), ..) => <Self as AsValue>::parse(v),
925    Value::Timestamp(Some(v), ..) => {
926        if v.time() != time::Time::MIDNIGHT {
927            return Err(anyhow!("Timestamp {v:?} cannot be converted to date because the time part is not midnight"))
928        }
929        Ok(v.date())
930    },
931    Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
932);
933
934impl_as_value!(
935    time::Time,
936    Value::Time,
937    |mut input: &str| {
938        let result: time::Time = parse_time!(
939            input,
940            "[hour]:[minute]:[second].[subsecond]",
941            "[hour]:[minute]:[second]",
942            "[hour]:[minute]",
943        )
944        .ok_or_else(|| anyhow!("Cannot parse `{}` as time::Time", truncate_long!(input)))?;
945        if !input.is_empty() {
946            return Err(anyhow!("Cannot parse `{}` as time::Time", truncate_long!(input)))
947        }
948        Ok(result)
949    },
950    Value::Interval(Some(v), ..) => {
951        let (h, m, s, ns) = v.as_hmsns();
952        if h < 0 || m < 0 || s < 0 || ns < 0 {
953            return Err(anyhow!(
954                "Cannot convert negative interval `{v:?}` to `time::Time`"
955            ));
956        }
957        time::Time::from_hms_nano(h as _, m as _, s as _, ns as _)
958            .map_err(|e| anyhow!("Cannot convert interval `{v:?}` to time: {e:?}"))
959    },
960    Value::Varchar(Some(v), ..) => <Self as AsValue>::parse(v),
961    Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
962);
963
964impl_as_value!(
965    time::PrimitiveDateTime,
966    Value::Timestamp,
967    |mut input: &str| {
968        let result: time::PrimitiveDateTime = parse_time!(
969            input,
970            "[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond]",
971            "[year]-[month]-[day]T[hour]:[minute]:[second]",
972            "[year]-[month]-[day]T[hour]:[minute]",
973            "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]",
974            "[year]-[month]-[day] [hour]:[minute]:[second]",
975            "[year]-[month]-[day] [hour]:[minute]",
976        )
977        .ok_or_else(|| anyhow!("Cannot parse `{}` as time::PrimitiveDateTime", truncate_long!(input)))?;
978        if !input.is_empty() {
979            return Err(anyhow!("Cannot parse `{}` as time::PrimitiveDateTime", truncate_long!(input)))
980        }
981        Ok(result)
982    },
983    Value::Varchar(Some(v), ..) => <Self as AsValue>::parse(v),
984    Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
985);
986
987impl AsValue for UtcDateTime {
988    fn as_empty_value() -> Value {
989        time::PrimitiveDateTime::as_empty_value()
990    }
991    fn as_value(self) -> Value {
992        PrimitiveDateTime::new(self.date(), self.time()).as_value()
993    }
994    fn try_from_value(value: Value) -> Result<Self>
995    where
996        Self: Sized,
997    {
998        PrimitiveDateTime::try_from_value(value).map(|v| Self::new(v.date(), v.time()))
999    }
1000}
1001
1002impl_as_value!(
1003    time::OffsetDateTime,
1004    Value::TimestampWithTimezone,
1005    |mut input: &str| {
1006        let original = input;
1007        if let Some(result) = parse_time!(
1008            input,
1009            "[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]:[offset_minute]:[offset_second]",
1010            "[year]-[month]-[day]T[hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]:[offset_second]",
1011            "[year]-[month]-[day]T[hour]:[minute][offset_hour sign:mandatory]:[offset_minute]:[offset_second]",
1012            "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]:[offset_minute]:[offset_second]",
1013            "[year]-[month]-[day] [hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]:[offset_second]",
1014            "[year]-[month]-[day] [hour]:[minute][offset_hour sign:mandatory]:[offset_minute]:[offset_second]",
1015            "[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]:[offset_minute]",
1016            "[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]",
1017            "[year]-[month]-[day]T[hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]",
1018            "[year]-[month]-[day]T[hour]:[minute]:[second][offset_hour sign:mandatory]",
1019            "[year]-[month]-[day]T[hour]:[minute][offset_hour sign:mandatory]:[offset_minute]",
1020            "[year]-[month]-[day]T[hour]:[minute][offset_hour sign:mandatory]",
1021            "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]:[offset_minute]",
1022            "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]",
1023            "[year]-[month]-[day] [hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]",
1024            "[year]-[month]-[day] [hour]:[minute]:[second][offset_hour sign:mandatory]",
1025            "[year]-[month]-[day] [hour]:[minute][offset_hour sign:mandatory]:[offset_minute]",
1026            "[year]-[month]-[day] [hour]:[minute][offset_hour sign:mandatory]",
1027        ) {
1028            if input.is_empty() {
1029                return Ok(result);
1030            }
1031        }
1032        if let Ok(result) = <PrimitiveDateTime as AsValue>::parse(original) {
1033            return Ok(result.assume_utc());
1034        }
1035        Err(anyhow!("Cannot parse `{}` as time::OffsetDateTime", truncate_long!(original)))
1036    },
1037    Value::Timestamp(Some(timestamp), ..) => Ok(timestamp.assume_utc()),
1038    Value::Varchar(Some(v), ..) => <Self as AsValue>::parse(v),
1039    Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
1040);
1041
1042#[cfg(feature = "chrono")]
1043impl AsValue for chrono::NaiveDate {
1044    fn as_empty_value() -> Value {
1045        Value::Date(None)
1046    }
1047    fn as_value(self) -> Value {
1048        Value::Date(
1049            'date: {
1050                time::Date::from_calendar_date(
1051                    self.year(),
1052                    number_to_month!(
1053                        self.month(),
1054                        break 'date Err(anyhow!("Unexpected month value {}", self.month()))
1055                    ),
1056                    self.day() as _,
1057                )
1058                .map_err(Into::into)
1059            }
1060            .inspect_err(|e| {
1061                log::error!("Could not create a Value::Date from chrono::NaiveDate: {e:?}");
1062            })
1063            .ok(),
1064        )
1065    }
1066    fn try_from_value(value: Value) -> Result<Self>
1067    where
1068        Self: Sized,
1069    {
1070        let value = <time::Date as AsValue>::try_from_value(value)
1071            .context("Could not create a chrono::NaiveDate")?;
1072        chrono::NaiveDate::from_ymd_opt(
1073            value.year(),
1074            month_to_number!(value.month()),
1075            value.day() as _,
1076        )
1077        .context("Could not create chrono::NaiveDate: from_ymd_opt returned None")
1078    }
1079}
1080
1081#[cfg(feature = "chrono")]
1082impl AsValue for chrono::NaiveTime {
1083    fn as_empty_value() -> Value {
1084        Value::Time(None)
1085    }
1086    fn as_value(self) -> Value {
1087        Value::Time(
1088            time::Time::from_hms_nano(
1089                self.hour() as _,
1090                self.minute() as _,
1091                self.second() as _,
1092                self.nanosecond() as _,
1093            )
1094            .inspect_err(|e| {
1095                log::error!("Could not create a Value::Time from chrono::NaiveTime: {e:?}",)
1096            })
1097            .ok(),
1098        )
1099    }
1100    fn try_from_value(value: Value) -> Result<Self>
1101    where
1102        Self: Sized,
1103    {
1104        let value = <time::Time as AsValue>::try_from_value(value)
1105            .context("Could not create a chrono::NaiveTime")?;
1106        Self::from_hms_nano_opt(
1107            value.hour() as _,
1108            value.minute() as _,
1109            value.second() as _,
1110            value.nanosecond() as _,
1111        )
1112        .context("Could not create chrono::NaiveTime: from_hms_nano_opt returned None")
1113    }
1114}
1115
1116#[cfg(feature = "chrono")]
1117impl AsValue for chrono::NaiveDateTime {
1118    fn as_empty_value() -> Value {
1119        Value::Timestamp(None)
1120    }
1121    fn as_value(self) -> Value {
1122        Value::Timestamp(
1123            'value: {
1124                let Ok(date) = AsValue::try_from_value(self.date().as_value()) else {
1125                    break 'value Err(anyhow!(
1126                        "Failed to convert the date part from chrono::NaiveDate to time::Date",
1127                    ));
1128                };
1129                let Ok(time) = AsValue::try_from_value(self.time().as_value()) else {
1130                    break 'value Err(anyhow!(
1131                        "Failed to convert the time part from chrono::NaiveTime to time::Time",
1132                    ));
1133                };
1134                Ok(time::PrimitiveDateTime::new(date, time))
1135            }
1136            .inspect_err(|e| {
1137                log::error!(
1138                    "Could not create a Value::Timestamp from chrono::NaiveDateTime: {e:?}",
1139                );
1140            })
1141            .ok(),
1142        )
1143    }
1144    fn try_from_value(value: Value) -> Result<Self>
1145    where
1146        Self: Sized,
1147    {
1148        let value = <time::PrimitiveDateTime as AsValue>::try_from_value(value)
1149            .context("Could not create a chrono::NaiveDateTime")?;
1150        let date = AsValue::try_from_value(value.date().as_value())
1151            .context("Could not convert date part of chrono::NaiveDateTime")?;
1152        let time = AsValue::try_from_value(value.time().as_value())
1153            .context("Could not convert time part of chrono::NaiveDateTime")?;
1154        Ok(Self::new(date, time))
1155    }
1156}
1157
1158#[cfg(feature = "chrono")]
1159impl AsValue for chrono::DateTime<chrono::FixedOffset> {
1160    fn as_empty_value() -> Value {
1161        Value::TimestampWithTimezone(None)
1162    }
1163    fn as_value(self) -> Value {
1164        Value::TimestampWithTimezone(
1165            'value: {
1166                let Ok(date) = AsValue::try_from_value(self.date_naive().as_value()) else {
1167                    break 'value Err(anyhow!(
1168                        "Failed to convert the date part from chrono::NaiveDate to time::Date",
1169                    ));
1170                };
1171                let Ok(time) = AsValue::try_from_value(self.time().as_value()) else {
1172                    break 'value Err(anyhow!(
1173                        "Failed to convert the time part from chrono::NaiveTime to time::Time",
1174                    ));
1175                };
1176                let Ok(offset) =
1177                    time::UtcOffset::from_whole_seconds(self.offset().fix().local_minus_utc())
1178                else {
1179                    break 'value Err(anyhow!("Failed to convert the offset part from"));
1180                };
1181                Ok(time::OffsetDateTime::new_in_offset(date, time, offset))
1182            }
1183            .inspect_err(|e| {
1184                log::error!(
1185                    "Could not create a Value::Timestamp from chrono::NaiveDateTime: {e:?}",
1186                );
1187            })
1188            .ok(),
1189        )
1190    }
1191    fn try_from_value(value: Value) -> Result<Self>
1192    where
1193        Self: Sized,
1194    {
1195        let value = <time::OffsetDateTime as AsValue>::try_from_value(value)
1196            .context("Could not create a chrono::DateTime")?;
1197        let utc = value.to_offset(time::UtcOffset::UTC);
1198        let date = AsValue::try_from_value(utc.date().as_value())
1199            .context("Could not convert date part of chrono::DateTime")?;
1200        let time = AsValue::try_from_value(utc.time().as_value())
1201            .context("Could not convert time part of chrono::DateTime")?;
1202        let date_time = chrono::NaiveDateTime::new(date, time);
1203        let offset = chrono::FixedOffset::east_opt(value.offset().whole_seconds())
1204            .context("Could not convert UTC offset part of chrono::DateTime")?;
1205        Ok(Self::from_naive_utc_and_offset(date_time, offset))
1206    }
1207}
1208
1209#[cfg(feature = "chrono")]
1210impl AsValue for chrono::DateTime<chrono::Utc> {
1211    fn as_empty_value() -> Value {
1212        Value::TimestampWithTimezone(None)
1213    }
1214    fn as_value(self) -> Value {
1215        let odt = self
1216            .timestamp_nanos_opt()
1217            .and_then(|nanos| time::OffsetDateTime::from_unix_timestamp_nanos(nanos as i128).ok());
1218        if odt.is_none() {
1219            log::error!(
1220                "Could not create a Value::TimestampWithTimezone from chrono::DateTime<Utc>: {self:?}",
1221            );
1222        }
1223        Value::TimestampWithTimezone(odt)
1224    }
1225    fn try_from_value(value: Value) -> Result<Self> {
1226        let odt = <time::OffsetDateTime as AsValue>::try_from_value(value)?;
1227        let utc_odt = odt.to_offset(time::UtcOffset::UTC);
1228        let secs = utc_odt.unix_timestamp();
1229        let nanos = utc_odt.nanosecond();
1230        Self::from_timestamp(secs, nanos)
1231            .ok_or_else(|| anyhow!("Timestamp out of range for chrono::DateTime<Utc>"))
1232    }
1233}
1234
1235impl AsValue for Decimal {
1236    fn as_empty_value() -> Value {
1237        Value::Decimal(None, 0, 0)
1238    }
1239    fn as_value(self) -> Value {
1240        Value::Decimal(Some(self), 0, self.scale() as _)
1241    }
1242    fn try_from_value(value: Value) -> Result<Self> {
1243        match value {
1244            Value::Decimal(Some(v), ..) => Ok(v),
1245            Value::Int8(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
1246            Value::Int16(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
1247            Value::Int32(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
1248            Value::Int64(Some(v), ..) => Ok(Decimal::new(v, 0)),
1249            Value::UInt8(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
1250            Value::UInt16(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
1251            Value::UInt32(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
1252            Value::UInt64(Some(v), ..) => Decimal::from_u64(v)
1253                .ok_or_else(|| anyhow!("Value {v}: u64 does not fit into Decimal")),
1254            Value::Float32(Some(v), ..) => {
1255                Decimal::from_f32(v).ok_or_else(|| anyhow!("Cannot convert {value:?} to Decimal"))
1256            }
1257            Value::Float64(Some(v), ..) => {
1258                Decimal::from_f64(v).ok_or_else(|| anyhow!("Cannot convert {value:?} to Decimal"))
1259            }
1260            Value::Json(Some(serde_json::Value::Number(v)), ..) => {
1261                if let Some(v) = v.as_f64()
1262                    && let Some(v) = Decimal::from_f64(v)
1263                {
1264                    Ok(v)
1265                } else {
1266                    Err(anyhow!(
1267                        "Value {v} from json number is out of range for Decimal",
1268                    ))
1269                }
1270            }
1271            Value::Unknown(Some(v), ..) => Self::parse(&v),
1272            Value::Varchar(Some(v)) => Self::parse(&v),
1273            _ => Err(anyhow!("Cannot convert {value:?} to Decimal")),
1274        }
1275    }
1276    fn parse(input: impl AsRef<str>) -> Result<Self> {
1277        let input = input.as_ref();
1278        Ok(input.parse::<Decimal>().with_context(|| {
1279            anyhow!(
1280                "Cannot parse a decimal value from `{}`",
1281                truncate_long!(input)
1282            )
1283        })?)
1284    }
1285}
1286
1287impl<const W: u8, const S: u8> AsValue for FixedDecimal<W, S> {
1288    fn as_empty_value() -> Value {
1289        Decimal::as_empty_value()
1290    }
1291    fn as_value(self) -> Value {
1292        Value::Decimal(Some(self.0), W, self.0.scale() as _)
1293    }
1294    fn try_from_value(value: Value) -> Result<Self>
1295    where
1296        Self: Sized,
1297    {
1298        Ok(Self(Decimal::try_from_value(value)?))
1299    }
1300    fn parse(input: impl AsRef<str>) -> Result<Self> {
1301        <Decimal as AsValue>::parse(input).map(Into::into)
1302    }
1303}
1304
1305impl<T: AsValue, const N: usize> AsValue for [T; N] {
1306    fn as_empty_value() -> Value {
1307        Value::Array(None, Box::new(T::as_empty_value()), N as u32)
1308    }
1309    fn as_value(self) -> Value {
1310        Value::Array(
1311            Some(self.into_iter().map(AsValue::as_value).collect()),
1312            Box::new(T::as_empty_value()),
1313            N as u32,
1314        )
1315    }
1316    fn try_from_value(value: Value) -> Result<Self> {
1317        fn convert_iter<T: AsValue, const N: usize>(
1318            iter: impl IntoIterator<Item: AsValue>,
1319        ) -> Result<[T; N]> {
1320            iter.into_iter()
1321                .map(|v| T::try_from_value(v.as_value()))
1322                .collect::<Result<Vec<_>>>()?
1323                .try_into()
1324                .map_err(|v: Vec<T>| {
1325                    anyhow!(
1326                        "Expected array of length {N}, got {} elements ({})",
1327                        v.len(),
1328                        any::type_name::<[T; N]>()
1329                    )
1330                })
1331        }
1332        match value {
1333            Value::Varchar(Some(v), ..)
1334                // Compare by count, not byte (for multi byte characters)
1335                if matches!(T::as_empty_value(), Value::Char(..)) && v.chars().count() == N =>
1336            {
1337                convert_iter(v.chars())
1338            }
1339            Value::List(Some(v), ..) if v.len() == N => convert_iter(v.into_iter()),
1340            Value::Array(Some(v), ..) if v.len() == N => convert_iter(v.into_iter()),
1341            Value::Json(Some(serde_json::Value::Array(v))) if v.len() == N => {
1342                convert_iter(v.into_iter())
1343            }
1344            Value::Unknown(Some(v)) => <Self as AsValue>::parse(v),
1345            _ => Err(anyhow!(
1346                "Cannot convert {value:?} to array {}",
1347                any::type_name::<Self>()
1348            )),
1349        }
1350    }
1351}
1352
1353macro_rules! impl_as_value {
1354    ($source:ident) => {
1355        impl<T: AsValue> AsValue for $source<T> {
1356            fn as_empty_value() -> Value {
1357                Value::List(None, Box::new(T::as_empty_value()))
1358            }
1359            fn as_value(self) -> Value {
1360                Value::List(
1361                    Some(self.into_iter().map(AsValue::as_value).collect()),
1362                    Box::new(T::as_empty_value()),
1363                )
1364            }
1365            fn try_from_value(value: Value) -> Result<Self> {
1366                match value {
1367                    Value::List(None, ..) => Ok(Default::default()),
1368                    Value::List(Some(v), ..) => Ok(v
1369                        .into_iter()
1370                        .map(|v| Ok::<_, Error>(<T as AsValue>::try_from_value(v)?))
1371                        .collect::<Result<_>>()?),
1372                    Value::Array(Some(v), ..) => Ok(v
1373                        .into_iter()
1374                        .map(|v| Ok::<_, Error>(<T as AsValue>::try_from_value(v)?))
1375                        .collect::<Result<_>>()?),
1376                    Value::Json(Some(serde_json::Value::Array(v)), ..) => Ok(v
1377                        .into_iter()
1378                        .map(|v| Ok::<_, Error>(<T as AsValue>::try_from_value(v.as_value())?))
1379                        .collect::<Result<_>>()?),
1380                    _ => Err(anyhow!(
1381                        "Cannot convert {value:?} to {}",
1382                        any::type_name::<Self>(),
1383                    )),
1384                }
1385            }
1386        }
1387    };
1388}
1389impl_as_value!(Vec);
1390impl_as_value!(VecDeque);
1391impl_as_value!(LinkedList);
1392
1393macro_rules! impl_as_value {
1394    ($source:ident, $($key_trait:ident),+) => {
1395        impl<K: AsValue $(+ $key_trait)+, V: AsValue> AsValue for $source<K, V> {
1396            fn as_empty_value() -> Value {
1397                Value::Map(None, K::as_empty_value().into(), V::as_empty_value().into())
1398            }
1399            fn as_value(self) -> Value {
1400                Value::Map(
1401                    Some(
1402                        self.into_iter()
1403                            .map(|(k, v)| (k.as_value(), v.as_value()))
1404                            .collect(),
1405                    ),
1406                    K::as_empty_value().into(),
1407                    V::as_empty_value().into(),
1408                )
1409            }
1410            fn try_from_value(value: Value) -> Result<Self> {
1411                match value {
1412                    Value::Map(None, ..) => Ok(Default::default()),
1413                    Value::Map(Some(v), ..) => {
1414                        Ok(v.into_iter()
1415                            .map(|(k, v)| {
1416                                Ok((
1417                                    <K as AsValue>::try_from_value(k)?,
1418                                    <V as AsValue>::try_from_value(v)?,
1419                                ))
1420                            })
1421                            .collect::<Result<_>>()?)
1422                    }
1423                    Value::Json(Some(serde_json::Value::Object(v)), ..) => {
1424                        Ok(v.into_iter()
1425                            .map(|(k, v)| {
1426                                Ok((
1427                                    <K as AsValue>::try_from_value(serde_json::Value::String(k).as_value())?,
1428                                    <V as AsValue>::try_from_value(v.as_value())?,
1429                                ))
1430                            })
1431                            .collect::<Result<_>>()?)
1432                    }
1433                    _=> {
1434                        Err(anyhow!(
1435                            "Cannot convert {value:?} to {}",
1436                            any::type_name::<Self>(),
1437                        ))
1438                    }
1439                }
1440            }
1441        }
1442    }
1443}
1444impl_as_value!(BTreeMap, Ord);
1445impl_as_value!(HashMap, Eq, Hash);
1446
1447impl AsValue for &'static str {
1448    fn as_empty_value() -> Value {
1449        Value::Varchar(None)
1450    }
1451    fn as_value(self) -> Value {
1452        Value::Varchar(Some(self.into()))
1453    }
1454    fn try_from_value(value: Value) -> Result<Self>
1455    where
1456        Self: Sized,
1457    {
1458        let Value::Varchar(Some(Cow::Borrowed(v))) = value.try_as(&Value::Varchar(None))? else {
1459            return Err(anyhow!(
1460                "Cannot assign a `&'static str` with data fetched from the database. Please consider `Cow<'static, str>` instead, can still use `&'static str` for data insertion purpose.",
1461            ));
1462        };
1463        Ok(v)
1464    }
1465}
1466
1467impl AsValue for Cow<'static, str> {
1468    fn as_empty_value() -> Value {
1469        Value::Varchar(None)
1470    }
1471    fn as_value(self) -> Value {
1472        Value::Varchar(Some(self.into()))
1473    }
1474    fn try_from_value(value: Value) -> Result<Self>
1475    where
1476        Self: Sized,
1477    {
1478        String::try_from_value(value).map(Into::into)
1479    }
1480    fn parse(input: impl AsRef<str>) -> Result<Self>
1481    where
1482        Self: Sized,
1483    {
1484        <String as AsValue>::parse(input).map(Into::into)
1485    }
1486}
1487
1488impl<T: AsValue> AsValue for Option<T> {
1489    fn as_empty_value() -> Value {
1490        T::as_empty_value()
1491    }
1492    fn as_value(self) -> Value {
1493        match self {
1494            Some(v) => v.as_value(),
1495            None => T::as_empty_value(),
1496        }
1497    }
1498    fn try_from_value(value: Value) -> Result<Self> {
1499        Ok(if value.is_null() {
1500            None
1501        } else {
1502            Some(<T as AsValue>::try_from_value(value)?)
1503        })
1504    }
1505    fn parse(input: impl AsRef<str>) -> Result<Self>
1506    where
1507        Self: Sized,
1508    {
1509        let mut value = input.as_ref();
1510        let result = consume_while(&mut value, |v| v.is_alphanumeric() || *v == '_');
1511        if result.eq_ignore_ascii_case("null") {
1512            return Ok(None);
1513        };
1514        T::parse(input).map(Some)
1515    }
1516}
1517
1518// TODO: Use the macro below once box_into_inner is stabilized
1519impl<T: AsValue> AsValue for Box<T> {
1520    fn as_empty_value() -> Value {
1521        T::as_empty_value()
1522    }
1523    fn as_value(self) -> Value {
1524        (*self).as_value()
1525    }
1526    fn try_from_value(value: Value) -> Result<Self> {
1527        Ok(Self::new(<T as AsValue>::try_from_value(value)?))
1528    }
1529    fn parse(input: impl AsRef<str>) -> Result<Self>
1530    where
1531        Self: Sized,
1532    {
1533        T::parse(input).map(Self::new)
1534    }
1535}
1536
1537macro_rules! impl_as_value {
1538    ($source:ident) => {
1539        impl<T: AsValue + ToOwned<Owned = impl AsValue>> AsValue for $source<T> {
1540            fn as_empty_value() -> Value {
1541                T::as_empty_value()
1542            }
1543            fn as_value(self) -> Value {
1544                $source::<T>::into_inner(self).as_value()
1545            }
1546            fn try_from_value(value: Value) -> Result<Self> {
1547                Ok($source::new(<T as AsValue>::try_from_value(value)?))
1548            }
1549        }
1550    };
1551}
1552// impl_as_value!(Box);
1553impl_as_value!(Cell);
1554impl_as_value!(RefCell);
1555
1556impl<T: AsValue> AsValue for RwLock<T> {
1557    fn as_empty_value() -> Value {
1558        T::as_empty_value()
1559    }
1560    fn as_value(self) -> Value {
1561        self.into_inner()
1562            .expect("Error occurred while trying to take the content of the RwLock")
1563            .as_value()
1564    }
1565    fn try_from_value(value: Value) -> Result<Self> {
1566        Ok(RwLock::new(<T as AsValue>::try_from_value(value)?))
1567    }
1568    fn parse(input: impl AsRef<str>) -> Result<Self>
1569    where
1570        Self: Sized,
1571    {
1572        T::parse(input).map(Self::new)
1573    }
1574}
1575
1576macro_rules! impl_as_value {
1577    ($source:ident) => {
1578        impl<T: AsValue + ToOwned<Owned = impl AsValue>> AsValue for $source<T> {
1579            fn as_empty_value() -> Value {
1580                T::as_empty_value()
1581            }
1582            fn as_value(self) -> Value {
1583                $source::try_unwrap(self)
1584                    .map(|v| v.as_value())
1585                    .unwrap_or_else(|v| v.as_ref().to_owned().as_value())
1586            }
1587            fn try_from_value(value: Value) -> Result<Self> {
1588                Ok($source::new(<T as AsValue>::try_from_value(value)?))
1589            }
1590            fn parse(input: impl AsRef<str>) -> Result<Self>
1591            where
1592                Self: Sized,
1593            {
1594                T::parse(input).map(Self::new)
1595            }
1596        }
1597    };
1598}
1599impl_as_value!(Arc);
1600impl_as_value!(Rc);
1601
1602impl AsValue for serde_json::Value {
1603    fn as_empty_value() -> Value {
1604        Value::Json(None)
1605    }
1606    fn as_value(self) -> Value {
1607        Value::Json(Some(self))
1608    }
1609    fn try_from_value(value: Value) -> Result<Self>
1610    where
1611        Self: Sized,
1612    {
1613        Ok(if let Value::Json(v) = value {
1614            match v {
1615                Some(v) => v,
1616                None => Self::Null,
1617            }
1618        } else {
1619            return Err(anyhow!(
1620                "Cannot convert non json tank::Value to serde_json::Value",
1621            ));
1622        })
1623    }
1624}