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