Skip to main content

tank_core/
as_value.rs

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