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