Skip to main content

tank_core/
as_value.rs

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