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