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