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