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