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