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