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).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 Value::Int8(Some(v), ..) => Ok(v.to_string()),
478 Value::Int16(Some(v), ..) => Ok(v.to_string()),
479 Value::Int32(Some(v), ..) => Ok(v.to_string()),
480 Value::Int64(Some(v), ..) => Ok(v.to_string()),
481 Value::Int128(Some(v), ..) => Ok(v.to_string()),
482 Value::UInt8(Some(v), ..) => Ok(v.to_string()),
483 Value::UInt16(Some(v), ..) => Ok(v.to_string()),
484 Value::UInt32(Some(v), ..) => Ok(v.to_string()),
485 Value::UInt64(Some(v), ..) => Ok(v.to_string()),
486 Value::UInt128(Some(v), ..) => Ok(v.to_string()),
487 Value::Float32(Some(v), ..) => Ok(v.to_string()),
488 Value::Float64(Some(v), ..) => Ok(v.to_string()),
489 Value::Decimal(Some(v), ..) => Ok(v.to_string()),
490 Value::Char(Some(v), ..) => Ok(v.into()),
491 Value::Date(Some(v), ..) => {
492 let mut out = String::new();
493 print_date(&mut out, "", &v);
494 Ok(out)
495 },
496 Value::Time(Some(v), ..) => {
497 let mut out = String::new();
498 print_timer(&mut out, "", v.hour() as _, v.minute(), v.second(), v.nanosecond());
499 Ok(out)
500 },
501 Value::Timestamp(Some(v), ..) => {
502 let date = v.date();
503 let time = v.time();
504 let mut out = String::new();
505 print_date(&mut out, "", &date);
506 out.push(' ');
507 print_timer(&mut out, "", time.hour() as _ , time.minute(), time.second(), time.nanosecond());
508 Ok(out)
509 },
510 Value::TimestampWithTimezone(Some(v), ..) => {
511 let date = v.date();
512 let time = v.time();
513 let mut out = String::new();
514 print_date(&mut out, "", &date);
515 out.push(' ');
516 print_timer(&mut out, "", time.hour() as _, time.minute(), time.second(), time.nanosecond());
517 let (h, m, s) = v.offset().as_hms();
518 out.push(' ');
519 if h >= 0 {
520 out.push('+');
521 } else {
522 out.push('-');
523 }
524 let offset = match Time::from_hms(h.abs() as _, m.abs() as _, s.abs() as _){
525 Ok(v) => v,
526 Err(e) => return Err(Error::new(e)),
527 };
528 print_timer(&mut out, "", offset.hour() as _, offset.minute(), offset.second(), offset.nanosecond());
529 Ok(out)
530 },
531 Value::Uuid(Some(v), ..) => Ok(v.to_string()),
532 Value::Json(Some(serde_json::Value::String(v)), ..) => Ok(v),
533);
534
535impl_as_value!(Box<[u8]>, Value::Blob, |mut input: &str| {
536 if input.starts_with("\\x") {
537 input = &input[2..];
538 }
539 let filter_x = input.contains('x');
540 let result = if filter_x {
541 hex::decode(input.chars().filter(|c| *c != 'x').collect::<String>())
542 } else {
543 hex::decode(input)
544 }
545 .map(Into::into)
546 .context(format!(
547 "While decoding `{}` as {}",
548 truncate_long!(input),
549 any::type_name::<Self>()
550 ))?;
551 Ok(result)
552});
553
554impl_as_value!(
555 Interval,
556 Value::Interval,
557 |mut input: &str| {
558 let context = || {
559 Error::msg(format!(
560 "Cannot parse interval from `{}`",
561 truncate_long!(input)
562 ))
563 .into()
564 };
565 match input.chars().peekable().peek() {
566 Some(v) if *v == '"' || *v == '\'' => {
567 input = &input[1..];
568 if !input.ends_with(*v) {
569 return Err(context());
570 }
571 input = input.trim_end_matches(*v);
572 }
573 _ => {}
574 };
575 let mut interval = Interval::ZERO;
576 loop {
577 let mut cur = input;
578 let Ok(count) = extract_number::<true>(&mut cur).parse::<i128>() else {
579 break;
580 };
581 cur = cur.trim_start();
582 let unit = consume_while(&mut cur, char::is_ascii_alphabetic);
583 if unit.is_empty() {
584 break;
585 }
586 match unit {
587 x if x.eq_ignore_ascii_case("y")
588 || x.eq_ignore_ascii_case("year")
589 || x.eq_ignore_ascii_case("years") =>
590 {
591 interval += Interval::from_years(count as _)
592 }
593 x if x.eq_ignore_ascii_case("mon")
594 || x.eq_ignore_ascii_case("mons")
595 || x.eq_ignore_ascii_case("month")
596 || x.eq_ignore_ascii_case("months") =>
597 {
598 interval += Interval::from_months(count as _)
599 }
600 x if x.eq_ignore_ascii_case("d")
601 || x.eq_ignore_ascii_case("day")
602 || x.eq_ignore_ascii_case("days") =>
603 {
604 interval += Interval::from_days(count as _)
605 }
606 x if x.eq_ignore_ascii_case("h")
607 || x.eq_ignore_ascii_case("hour")
608 || x.eq_ignore_ascii_case("hours") =>
609 {
610 interval += Interval::from_hours(count as _)
611 }
612 x if x.eq_ignore_ascii_case("min")
613 || x.eq_ignore_ascii_case("mins")
614 || x.eq_ignore_ascii_case("minute")
615 || x.eq_ignore_ascii_case("minutes") =>
616 {
617 interval += Interval::from_mins(count as _)
618 }
619 x if x.eq_ignore_ascii_case("s")
620 || x.eq_ignore_ascii_case("sec")
621 || x.eq_ignore_ascii_case("secs")
622 || x.eq_ignore_ascii_case("second")
623 || x.eq_ignore_ascii_case("seconds") =>
624 {
625 interval += Interval::from_secs(count as _)
626 }
627 x if x.eq_ignore_ascii_case("micro")
628 || x.eq_ignore_ascii_case("micros")
629 || x.eq_ignore_ascii_case("microsecond")
630 || x.eq_ignore_ascii_case("microseconds") =>
631 {
632 interval += Interval::from_micros(count as _)
633 }
634 x if x.eq_ignore_ascii_case("ns")
635 || x.eq_ignore_ascii_case("nano")
636 || x.eq_ignore_ascii_case("nanos")
637 || x.eq_ignore_ascii_case("nanosecond")
638 || x.eq_ignore_ascii_case("nanoseconds") =>
639 {
640 interval += Interval::from_nanos(count as _)
641 }
642 _ => return Err(context()),
643 }
644 input = cur.trim_start();
645 }
646 let neg = if Some('-') == input.chars().next() {
647 input = input[1..].trim_ascii_start();
648 true
649 } else {
650 false
651 };
652 let mut time_interval = Interval::ZERO;
653 let num = extract_number::<true>(&mut input);
654 if !num.is_empty() {
655 let num = num.parse::<u64>().with_context(context)?;
656 time_interval += Interval::from_hours(num as _);
657 if Some(':') == input.chars().next() {
658 input = &input[1..];
659 let num = extract_number::<false>(&mut input).parse::<u64>()?;
660 if input.is_empty() {
661 return Err(context());
662 }
663 time_interval += Interval::from_mins(num as _);
664 if Some(':') == input.chars().next() {
665 input = &input[1..];
666 let num = extract_number::<false>(&mut input)
667 .parse::<u64>()
668 .with_context(context)?;
669 time_interval += Interval::from_secs(num as _);
670 if Some('.') == input.chars().next() {
671 input = &input[1..];
672 let len = input.len();
673 let mut num = extract_number::<true>(&mut input)
674 .parse::<i128>()
675 .with_context(context)?;
676 let magnitude = (len - 1) / 3;
677 num *= 10_i128.pow(2 - (len + 2) as u32 % 3);
678 match magnitude {
679 0 => time_interval += Interval::from_millis(num),
680 1 => time_interval += Interval::from_micros(num),
681 2 => time_interval += Interval::from_nanos(num),
682 _ => return Err(context()),
683 }
684 }
685 }
686 }
687 if neg {
688 interval -= time_interval;
689 } else {
690 interval += time_interval;
691 }
692 }
693 if !input.is_empty() {
694 return Err(context());
695 }
696 Ok(interval)
697 },
698 Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
699);
700
701impl_as_value!(
702 std::time::Duration,
703 Value::Interval,
704 |v| <Interval as AsValue>::parse(v).map(Into::into),
705 Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
706);
707
708impl_as_value!(
709 time::Duration,
710 Value::Interval,
711 |v| <Interval as AsValue>::parse(v).map(Into::into),
712 Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
713);
714
715impl_as_value!(
716 Uuid,
717 Value::Uuid,
718 |input: &str| {
719 let uuid = Uuid::parse_str(input).with_context(|| {
720 format!(
721 "Cannot parse a uuid value from `{}`",
722 truncate_long!(input)
723 )
724 })?;
725 Ok(uuid)
726 },
727 Value::Varchar(Some(v), ..) => <Self as AsValue>::parse(v),
728 Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
729);
730
731macro_rules! parse_time {
732 ($value: ident, $($formats:literal),+ $(,)?) => {
733 'value: {
734 let context = || Error::msg(format!(
735 "Cannot parse `{}` as {}",
736 truncate_long!($value),
737 any::type_name::<Self>()
738 ));
739 for format in [$($formats,)+] {
740 let format = parse_borrowed::<2>(format)?;
741 let mut parsed = time::parsing::Parsed::new();
742 let remaining = parsed.parse_items($value.as_bytes(), &format);
743 if let Ok(remaining) = remaining {
744 let result = parsed.try_into().with_context(context)?;
745 $value = &$value[($value.len() - remaining.len())..];
746 break 'value Ok(result);
747 }
748 }
749 Err(context())
750 }
751 }
752}
753
754impl_as_value!(
755 time::Date,
756 Value::Date,
757 |input: &str| {
758 let mut value = input;
759 let mut result: time::Date = parse_time!(value, "[year]-[month]-[day]")?;
760 {
761 let mut attempt = value.trim_start();
762 let suffix = consume_while(&mut attempt, char::is_ascii_alphabetic);
763 if suffix.eq_ignore_ascii_case("bc") {
764 result =
765 time::Date::from_calendar_date(-(result.year() - 1), result.month(), result.day())?;
766 value = attempt;
767 }
768 if suffix.eq_ignore_ascii_case("ad") {
769 value = attempt
770 }
771 }
772 if !value.is_empty() {
773 return Err(Error::msg(format!("Cannot parse `{}` as time::Date", truncate_long!(input))))
774 }
775 Ok(result)
776 },
777 Value::Varchar(Some(v), ..) => <Self as AsValue>::parse(v),
778 Value::Timestamp(Some(v), ..) => {
779 if v.time() != time::Time::MIDNIGHT {
780 return Err(Error::msg(format!("Timestamp {v:?} cannot be converted to date because the time part is not midnight")))
781 }
782 Ok(v.date())
783 },
784 Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
785);
786
787impl_as_value!(
788 time::Time,
789 Value::Time,
790 |mut input: &str| {
791 let result: time::Time = parse_time!(
792 input,
793 "[hour]:[minute]:[second].[subsecond]",
794 "[hour]:[minute]:[second]",
795 "[hour]:[minute]",
796 )?;
797 if !input.is_empty() {
798 return Err(Error::msg(format!("Cannot parse `{}` as time::Time", truncate_long!(input))))
799 }
800 Ok(result)
801 },
802 Value::Interval(Some(v), ..) => {
803 let (h, m, s, ns) = v.as_hmsns();
804 time::Time::from_hms_nano(h as _, m, s, ns,)
805 .map_err(|e| Error::msg(format!("Cannot convert interval `{v:?}` into time: {e:?}")))
806 },
807 Value::Varchar(Some(v), ..) => <Self as AsValue>::parse(v),
808 Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
809);
810
811impl_as_value!(
812 time::PrimitiveDateTime,
813 Value::Timestamp,
814 |mut input: &str| {
815 let result: time::PrimitiveDateTime = parse_time!(
816 input,
817 "[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond]",
818 "[year]-[month]-[day]T[hour]:[minute]:[second]",
819 "[year]-[month]-[day]T[hour]:[minute]",
820 "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]",
821 "[year]-[month]-[day] [hour]:[minute]:[second]",
822 "[year]-[month]-[day] [hour]:[minute]",
823 )?;
824 if !input.is_empty() {
825 return Err(Error::msg(format!("Cannot parse `{}` as time::PrimitiveDateTime", truncate_long!(input))))
826 }
827 Ok(result)
828 },
829 Value::Varchar(Some(v), ..) => <Self as AsValue>::parse(v),
830 Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
831);
832
833impl_as_value!(
834 time::OffsetDateTime,
835 Value::TimestampWithTimezone,
836 |mut input: &str| {
837 if let Ok::<time::OffsetDateTime, _>(result) = parse_time!(
838 input,
839 "[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]:[offset_minute]",
840 "[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]",
841 "[year]-[month]-[day]T[hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]",
842 "[year]-[month]-[day]T[hour]:[minute]:[second][offset_hour sign:mandatory]",
843 "[year]-[month]-[day]T[hour]:[minute][offset_hour sign:mandatory]:[offset_minute]",
844 "[year]-[month]-[day]T[hour]:[minute][offset_hour sign:mandatory]",
845 "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]:[offset_minute]",
846 "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]",
847 "[year]-[month]-[day] [hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]",
848 "[year]-[month]-[day] [hour]:[minute]:[second][offset_hour sign:mandatory]",
849 "[year]-[month]-[day] [hour]:[minute][offset_hour sign:mandatory]:[offset_minute]",
850 "[year]-[month]-[day] [hour]:[minute][offset_hour sign:mandatory]",
851 ) {
852 return Ok(result);
853 }
854 if let Ok(result) = <PrimitiveDateTime as AsValue>::parse(input).map(|v| v.assume_utc()) {
855 return Ok(result);
856 }
857 Err(Error::msg(format!("Cannot parse `{}` as time::OffsetDateTime", truncate_long!(input))))
858 },
859 Value::Timestamp(Some(timestamp), ..) => Ok(timestamp.assume_utc()),
860 Value::Varchar(Some(v), ..) => <Self as AsValue>::parse(v),
861 Value::Json(Some(serde_json::Value::String(ref v)), ..) => <Self as AsValue>::parse(v),
862);
863
864#[cfg(feature = "chrono")]
865impl AsValue for chrono::NaiveDate {
866 fn as_empty_value() -> Value {
867 Value::Date(None)
868 }
869 fn as_value(self) -> Value {
870 Value::Date(
871 'date: {
872 time::Date::from_calendar_date(
873 self.year(),
874 number_to_month!(
875 self.month(),
876 break 'date Err(Error::msg(format!(
877 "Unexpected month value {}",
878 self.month()
879 )))
880 ),
881 self.day() as _,
882 )
883 .map_err(Into::into)
884 }
885 .inspect_err(|e| {
886 log::error!("Could not create a Value::Date from chrono::NaiveDate: {e:?}");
887 })
888 .ok(),
889 )
890 }
891 fn try_from_value(value: Value) -> Result<Self>
892 where
893 Self: Sized,
894 {
895 let context = Arc::new(format!(
896 "Could not create a chrono::NaiveDate from {value:?}"
897 ));
898 let v = <time::Date as AsValue>::try_from_value(value).context(context.clone())?;
899 chrono::NaiveDate::from_ymd_opt(v.year(), month_to_number!(v.month()), v.day() as _)
900 .context(context)
901 }
902}
903
904#[cfg(feature = "chrono")]
905impl AsValue for chrono::NaiveTime {
906 fn as_empty_value() -> Value {
907 Value::Time(None)
908 }
909 fn as_value(self) -> Value {
910 Value::Time(
911 time::Time::from_hms_nano(
912 self.hour() as _,
913 self.minute() as _,
914 self.second() as _,
915 self.nanosecond() as _,
916 )
917 .inspect_err(|e| {
918 log::error!("Could not create a Value::Time from chrono::NaiveTime: {e:?}",)
919 })
920 .ok(),
921 )
922 }
923 fn try_from_value(value: Value) -> Result<Self>
924 where
925 Self: Sized,
926 {
927 let context = Arc::new(format!(
928 "Could not create a chrono::NaiveTime from {value:?}"
929 ));
930 let v = <time::Time as AsValue>::try_from_value(value).context(context.clone())?;
931 Self::from_hms_nano_opt(
932 v.hour() as _,
933 v.minute() as _,
934 v.second() as _,
935 v.nanosecond() as _,
936 )
937 .context(context)
938 }
939}
940
941#[cfg(feature = "chrono")]
942impl AsValue for chrono::NaiveDateTime {
943 fn as_empty_value() -> Value {
944 Value::Timestamp(None)
945 }
946 fn as_value(self) -> Value {
947 Value::Timestamp(
948 'value: {
949 let Ok(date) = AsValue::try_from_value(self.date().as_value()) else {
950 break 'value Err(Error::msg(
951 "failed to convert the date part from chrono::NaiveDate to time::Date",
952 ));
953 };
954 let Ok(time) = AsValue::try_from_value(self.time().as_value()) else {
955 break 'value Err(Error::msg(
956 "failed to convert the time part from chrono::NaiveTime to time::Time",
957 ));
958 };
959 Ok(time::PrimitiveDateTime::new(date, time))
960 }
961 .inspect_err(|e| {
962 log::error!(
963 "Could not create a Value::Timestamp from chrono::NaiveDateTime: {e:?}",
964 );
965 })
966 .ok(),
967 )
968 }
969 fn try_from_value(value: Value) -> Result<Self>
970 where
971 Self: Sized,
972 {
973 let context = Arc::new(format!(
974 "Could not create a chrono::NaiveDateTime from {value:?}"
975 ));
976 let v =
977 <time::PrimitiveDateTime as AsValue>::try_from_value(value).context(context.clone())?;
978 let date = AsValue::try_from_value(v.date().as_value()).context(context.clone())?;
979 let time = AsValue::try_from_value(v.time().as_value()).context(context.clone())?;
980 Ok(Self::new(date, time))
981 }
982}
983
984#[cfg(feature = "chrono")]
985impl AsValue for chrono::DateTime<chrono::FixedOffset> {
986 fn as_empty_value() -> Value {
987 Value::TimestampWithTimezone(None)
988 }
989 fn as_value(self) -> Value {
990 Value::TimestampWithTimezone(
991 'value: {
992 use chrono::Offset;
993 let Ok(date) = AsValue::try_from_value(self.date_naive().as_value()) else {
994 break 'value Err(Error::msg(
995 "failed to convert the date part from chrono::NaiveDate to time::Date",
996 ));
997 };
998 let Ok(time) = AsValue::try_from_value(self.time().as_value()) else {
999 break 'value Err(Error::msg(
1000 "failed to convert the time part from chrono::NaiveTime to time::Time",
1001 ));
1002 };
1003 let Ok(offset) =
1004 time::UtcOffset::from_whole_seconds(self.offset().fix().local_minus_utc())
1005 else {
1006 break 'value Err(Error::msg("failed to convert the offset part from"));
1007 };
1008 Ok(time::OffsetDateTime::new_in_offset(date, time, offset))
1009 }
1010 .inspect_err(|e| {
1011 log::error!(
1012 "Could not create a Value::Timestamp from chrono::NaiveDateTime: {e:?}",
1013 );
1014 })
1015 .ok(),
1016 )
1017 }
1018 fn try_from_value(value: Value) -> Result<Self>
1019 where
1020 Self: Sized,
1021 {
1022 let context = Arc::new(format!(
1023 "Could not create a chrono::DateTime from {value:?}"
1024 ));
1025 let v =
1026 <time::OffsetDateTime as AsValue>::try_from_value(value).context(context.clone())?;
1027 let date = AsValue::try_from_value(v.date().as_value()).context(context.clone())?;
1028 let time = AsValue::try_from_value(v.time().as_value()).context(context.clone())?;
1029 let date_time = chrono::NaiveDateTime::new(date, time);
1030 let offset =
1031 chrono::FixedOffset::east_opt(v.offset().whole_seconds()).context(context.clone())?;
1032 Ok(Self::from_naive_utc_and_offset(date_time, offset))
1033 }
1034}
1035
1036#[cfg(feature = "chrono")]
1037impl AsValue for chrono::DateTime<chrono::Utc> {
1038 fn as_empty_value() -> Value {
1039 Value::TimestampWithTimezone(None)
1040 }
1041 fn as_value(self) -> Value {
1042 let odt = time::OffsetDateTime::from_unix_timestamp_nanos(
1043 self.timestamp_nanos_opt().unwrap() as i128,
1044 )
1045 .unwrap();
1046 Value::TimestampWithTimezone(Some(odt))
1047 }
1048 fn try_from_value(value: Value) -> Result<Self> {
1049 let odt = <time::OffsetDateTime as AsValue>::try_from_value(value)?;
1050 let utc_odt = odt.to_offset(time::UtcOffset::UTC);
1051 let secs = utc_odt.unix_timestamp();
1052 let nanos = utc_odt.nanosecond();
1053 Self::from_timestamp(secs, nanos)
1054 .ok_or_else(|| Error::msg("Timestamp out of range for chrono::DateTime<Utc>"))
1055 }
1056}
1057
1058impl AsValue for Decimal {
1059 fn as_empty_value() -> Value {
1060 Value::Decimal(None, 0, 0)
1061 }
1062 fn as_value(self) -> Value {
1063 Value::Decimal(Some(self), 0, self.scale() as _)
1064 }
1065 fn try_from_value(value: Value) -> Result<Self> {
1066 match value {
1067 Value::Decimal(Some(v), ..) => Ok(v),
1068 Value::Int8(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
1069 Value::Int16(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
1070 Value::Int32(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
1071 Value::Int64(Some(v), ..) => Ok(Decimal::new(v, 0)),
1072 Value::UInt8(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
1073 Value::UInt16(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
1074 Value::UInt32(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
1075 Value::UInt64(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
1076 Value::Float32(Some(v), ..) => Ok(Decimal::from_f32(v)
1077 .ok_or(Error::msg(format!("Cannot convert {value:?} to Decimal")))?),
1078 Value::Float64(Some(v), ..) => Ok(Decimal::from_f64(v)
1079 .ok_or(Error::msg(format!("Cannot convert {value:?} to Decimal")))?),
1080 Value::Json(Some(serde_json::Value::Number(v)), ..) => {
1081 if let Some(v) = v.as_f64()
1082 && let Some(v) = Decimal::from_f64(v)
1083 {
1084 return Ok(v);
1085 }
1086 Err(Error::msg(format!(
1087 "Value {v} from json number is out of range for Decimal",
1088 )))
1089 }
1090 Value::Unknown(Some(v), ..) => Self::parse(&v),
1091 Value::Varchar(Some(v)) => Self::parse(&v),
1092 _ => Err(Error::msg(format!("Cannot convert {value:?} to Decimal"))),
1093 }
1094 }
1095 fn parse(input: impl AsRef<str>) -> Result<Self> {
1096 let input = input.as_ref();
1097 Ok(input.parse::<Decimal>().with_context(|| {
1098 Error::msg(format!(
1099 "Cannot parse a decimal value from `{}`",
1100 truncate_long!(input)
1101 ))
1102 })?)
1103 }
1104}
1105
1106impl<const W: u8, const S: u8> AsValue for FixedDecimal<W, S> {
1107 fn as_empty_value() -> Value {
1108 Decimal::as_empty_value()
1109 }
1110 fn as_value(self) -> Value {
1111 Value::Decimal(Some(self.0), W, self.0.scale() as _)
1112 }
1113 fn try_from_value(value: Value) -> Result<Self>
1114 where
1115 Self: Sized,
1116 {
1117 Ok(Self(Decimal::try_from_value(value)?))
1118 }
1119 fn parse(input: impl AsRef<str>) -> Result<Self> {
1120 <Decimal as AsValue>::parse(input).map(Into::into)
1121 }
1122}
1123
1124impl<T: AsValue, const N: usize> AsValue for [T; N] {
1125 fn as_empty_value() -> Value {
1126 Value::Array(None, Box::new(T::as_empty_value()), N as u32)
1127 }
1128 fn as_value(self) -> Value {
1129 Value::Array(
1130 Some(self.into_iter().map(AsValue::as_value).collect()),
1131 Box::new(T::as_empty_value()),
1132 N as u32,
1133 )
1134 }
1135 fn try_from_value(value: Value) -> Result<Self> {
1136 fn convert_iter<T: AsValue, const N: usize>(
1137 iter: impl IntoIterator<Item: AsValue>,
1138 ) -> Result<[T; N]> {
1139 iter.into_iter()
1140 .map(|v| T::try_from_value(v.as_value()))
1141 .collect::<Result<Vec<_>>>()?
1142 .try_into()
1143 .map_err(|v: Vec<T>| {
1144 Error::msg(format!(
1145 "Expected array of length {N}, got {} elements ({})",
1146 v.len(),
1147 any::type_name::<[T; N]>()
1148 ))
1149 })
1150 }
1151 match value {
1152 Value::Varchar(Some(v), ..)
1153 if matches!(T::as_empty_value(), Value::Char(..)) && v.len() == N =>
1154 {
1155 convert_iter(v.chars())
1156 }
1157 Value::List(Some(v), ..) if v.len() == N => convert_iter(v.into_iter()),
1158 Value::Array(Some(v), ..) if v.len() == N => convert_iter(v.into_iter()),
1159 Value::Json(Some(serde_json::Value::Array(v))) if v.len() == N => {
1160 convert_iter(v.into_iter())
1161 }
1162 Value::Unknown(Some(v)) => <Self as AsValue>::parse(v),
1163 _ => Err(Error::msg(format!(
1164 "Cannot convert {value:?} to array {}",
1165 any::type_name::<Self>()
1166 ))),
1167 }
1168 }
1169}
1170
1171macro_rules! impl_as_value {
1172 ($source:ident) => {
1173 impl<T: AsValue> AsValue for $source<T> {
1174 fn as_empty_value() -> Value {
1175 Value::List(None, Box::new(T::as_empty_value()))
1176 }
1177 fn as_value(self) -> Value {
1178 Value::List(
1179 Some(self.into_iter().map(AsValue::as_value).collect()),
1180 Box::new(T::as_empty_value()),
1181 )
1182 }
1183 fn try_from_value(value: Value) -> Result<Self> {
1184 match value {
1185 Value::List(None, ..) => Ok(Default::default()),
1186 Value::List(Some(v), ..) => Ok(v
1187 .into_iter()
1188 .map(|v| Ok::<_, Error>(<T as AsValue>::try_from_value(v)?))
1189 .collect::<Result<_>>()?),
1190 Value::Array(Some(v), ..) => Ok(v
1191 .into_iter()
1192 .map(|v| Ok::<_, Error>(<T as AsValue>::try_from_value(v)?))
1193 .collect::<Result<_>>()?),
1194 Value::Json(Some(serde_json::Value::Array(v)), ..) => Ok(v
1195 .into_iter()
1196 .map(|v| Ok::<_, Error>(<T as AsValue>::try_from_value(v.as_value())?))
1197 .collect::<Result<_>>()?),
1198 _ => Err(Error::msg(format!(
1199 "Cannot convert {value:?} to {}",
1200 any::type_name::<Self>(),
1201 ))),
1202 }
1203 }
1204 }
1205 };
1206}
1207impl_as_value!(Vec);
1208impl_as_value!(VecDeque);
1209impl_as_value!(LinkedList);
1210
1211macro_rules! impl_as_value {
1212 ($source:ident, $($key_trait:ident),+) => {
1213 impl<K: AsValue $(+ $key_trait)+, V: AsValue> AsValue for $source<K, V> {
1214 fn as_empty_value() -> Value {
1215 Value::Map(None, K::as_empty_value().into(), V::as_empty_value().into())
1216 }
1217 fn as_value(self) -> Value {
1218 Value::Map(
1219 Some(
1220 self.into_iter()
1221 .map(|(k, v)| (k.as_value(), v.as_value()))
1222 .collect(),
1223 ),
1224 K::as_empty_value().into(),
1225 V::as_empty_value().into(),
1226 )
1227 }
1228 fn try_from_value(value: Value) -> Result<Self> {
1229 match value {
1230 Value::Map(None, ..) => Ok(Default::default()),
1231 Value::Map(Some(v), ..) => {
1232 Ok(v.into_iter()
1233 .map(|(k, v)| {
1234 Ok((
1235 <K as AsValue>::try_from_value(k)?,
1236 <V as AsValue>::try_from_value(v)?,
1237 ))
1238 })
1239 .collect::<Result<_>>()?)
1240 }
1241 Value::Json(Some(serde_json::Value::Object(v)), ..) => {
1242 Ok(v.into_iter()
1243 .map(|(k, v)| {
1244 Ok((
1245 <K as AsValue>::try_from_value(serde_json::Value::String(k).as_value())?,
1246 <V as AsValue>::try_from_value(v.as_value())?,
1247 ))
1248 })
1249 .collect::<Result<_>>()?)
1250 }
1251 _=> {
1252 Err(Error::msg(format!(
1253 "Cannot convert {value:?} to {}",
1254 any::type_name::<Self>(),
1255 )))
1256 }
1257 }
1258 }
1259 }
1260 }
1261}
1262impl_as_value!(BTreeMap, Ord);
1263impl_as_value!(HashMap, Eq, Hash);
1264
1265impl AsValue for &'static str {
1266 fn as_empty_value() -> Value {
1267 Value::Varchar(None)
1268 }
1269 fn as_value(self) -> Value {
1270 Value::Varchar(Some(self.into()))
1271 }
1272 fn try_from_value(value: Value) -> Result<Self>
1273 where
1274 Self: Sized,
1275 {
1276 let Value::Varchar(Some(Cow::Borrowed(v))) = value.try_as(&Value::Varchar(None))? else {
1277 return Err(Error::msg(format!(
1278 "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.",
1279 )));
1280 };
1281 Ok(v)
1282 }
1283}
1284
1285impl AsValue for Cow<'static, str> {
1286 fn as_empty_value() -> Value {
1287 Value::Varchar(None)
1288 }
1289 fn as_value(self) -> Value {
1290 Value::Varchar(Some(self.into()))
1291 }
1292 fn try_from_value(value: Value) -> Result<Self>
1293 where
1294 Self: Sized,
1295 {
1296 String::try_from_value(value).map(Into::into)
1297 }
1298 fn parse(input: impl AsRef<str>) -> Result<Self>
1299 where
1300 Self: Sized,
1301 {
1302 <String as AsValue>::parse(input).map(Into::into)
1303 }
1304}
1305
1306impl<T: AsValue> AsValue for Passive<T> {
1307 fn as_empty_value() -> Value {
1308 T::as_empty_value()
1309 }
1310 fn as_value(self) -> Value {
1311 match self {
1312 Passive::Set(v) => v.as_value(),
1313 Passive::NotSet => T::as_empty_value(),
1314 }
1315 }
1316 fn try_from_value(value: Value) -> Result<Self> {
1317 Ok(Passive::Set(<T as AsValue>::try_from_value(value)?))
1318 }
1319}
1320
1321impl<T: AsValue> AsValue for Option<T> {
1322 fn as_empty_value() -> Value {
1323 T::as_empty_value()
1324 }
1325 fn as_value(self) -> Value {
1326 match self {
1327 Some(v) => v.as_value(),
1328 None => T::as_empty_value(),
1329 }
1330 }
1331 fn try_from_value(value: Value) -> Result<Self> {
1332 Ok(if value.is_null() {
1333 None
1334 } else {
1335 Some(<T as AsValue>::try_from_value(value)?)
1336 })
1337 }
1338 fn parse(input: impl AsRef<str>) -> Result<Self>
1339 where
1340 Self: Sized,
1341 {
1342 let mut value = input.as_ref();
1343 let result = consume_while(&mut value, |v| v.is_alphanumeric() || *v == '_');
1344 if result.eq_ignore_ascii_case("null") {
1345 return Ok(None);
1346 };
1347 T::parse(input).map(Some)
1348 }
1349}
1350
1351impl<T: AsValue> AsValue for Box<T> {
1353 fn as_empty_value() -> Value {
1354 T::as_empty_value()
1355 }
1356 fn as_value(self) -> Value {
1357 (*self).as_value()
1358 }
1359 fn try_from_value(value: Value) -> Result<Self> {
1360 Ok(Self::new(<T as AsValue>::try_from_value(value)?))
1361 }
1362 fn parse(input: impl AsRef<str>) -> Result<Self>
1363 where
1364 Self: Sized,
1365 {
1366 T::parse(input).map(Self::new)
1367 }
1368}
1369
1370macro_rules! impl_as_value {
1371 ($source:ident) => {
1372 impl<T: AsValue + ToOwned<Owned = impl AsValue>> AsValue for $source<T> {
1373 fn as_empty_value() -> Value {
1374 T::as_empty_value()
1375 }
1376 fn as_value(self) -> Value {
1377 $source::<T>::into_inner(self).as_value()
1378 }
1379 fn try_from_value(value: Value) -> Result<Self> {
1380 Ok($source::new(<T as AsValue>::try_from_value(value)?))
1381 }
1382 }
1383 };
1384}
1385impl_as_value!(Cell);
1387impl_as_value!(RefCell);
1388
1389impl<T: AsValue> AsValue for RwLock<T> {
1390 fn as_empty_value() -> Value {
1391 T::as_empty_value()
1392 }
1393 fn as_value(self) -> Value {
1394 self.into_inner()
1395 .expect("Error occurred while trying to take the content of the RwLock")
1396 .as_value()
1397 }
1398 fn try_from_value(value: Value) -> Result<Self> {
1399 Ok(RwLock::new(<T as AsValue>::try_from_value(value)?))
1400 }
1401 fn parse(input: impl AsRef<str>) -> Result<Self>
1402 where
1403 Self: Sized,
1404 {
1405 T::parse(input).map(Self::new)
1406 }
1407}
1408
1409macro_rules! impl_as_value {
1410 ($source:ident) => {
1411 impl<T: AsValue + ToOwned<Owned = impl AsValue>> AsValue for $source<T> {
1412 fn as_empty_value() -> Value {
1413 T::as_empty_value()
1414 }
1415 fn as_value(self) -> Value {
1416 $source::try_unwrap(self)
1417 .map(|v| v.as_value())
1418 .unwrap_or_else(|v| v.as_ref().to_owned().as_value())
1419 }
1420 fn try_from_value(value: Value) -> Result<Self> {
1421 Ok($source::new(<T as AsValue>::try_from_value(value)?))
1422 }
1423 fn parse(input: impl AsRef<str>) -> Result<Self>
1424 where
1425 Self: Sized,
1426 {
1427 T::parse(input).map(Self::new)
1428 }
1429 }
1430 };
1431}
1432impl_as_value!(Arc);
1433impl_as_value!(Rc);
1434
1435impl AsValue for serde_json::Value {
1436 fn as_empty_value() -> Value {
1437 Value::Json(None)
1438 }
1439 fn as_value(self) -> Value {
1440 Value::Json(Some(self))
1441 }
1442 fn try_from_value(value: Value) -> Result<Self>
1443 where
1444 Self: Sized,
1445 {
1446 Ok(if let Value::Json(v) = value {
1447 match v {
1448 Some(v) => v,
1449 None => Self::Null,
1450 }
1451 } else {
1452 return Err(Error::msg(
1453 "Cannot convert non json tank::Value to serde_json::Value",
1454 ));
1455 })
1456 }
1457}