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