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