Skip to main content

tank_core/
as_value.rs

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