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