Skip to main content

tank_core/
as_value.rs

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