1use crate::{Error, FixedDecimal, Interval, Passive, Result, Value, consume_while, truncate_long};
2use anyhow::Context;
3use atoi::{FromRadix10, FromRadix10Signed};
4use fast_float::parse_partial;
5use rust_decimal::{Decimal, prelude::FromPrimitive, prelude::ToPrimitive};
6use std::{
7 any, array,
8 borrow::Cow,
9 cell::{Cell, RefCell},
10 collections::{BTreeMap, HashMap, LinkedList, VecDeque},
11 hash::Hash,
12 mem,
13 rc::Rc,
14 sync::{Arc, RwLock},
15};
16use time::{PrimitiveDateTime, format_description::parse_borrowed};
17use uuid::Uuid;
18
19pub trait AsValue {
20 fn as_empty_value() -> Value;
21 fn as_value(self) -> Value;
22 fn try_from_value(value: Value) -> Result<Self>
23 where
24 Self: Sized;
25 fn parse(input: impl AsRef<str>) -> Result<Self>
26 where
27 Self: Sized,
28 {
29 let mut value = input.as_ref();
30 let result = Self::extract(&mut value)?;
31 if !value.is_empty() {
32 return Err(Error::msg(format!(
33 "Value `{}` parsed correctly as {} but it did not consume all the input (remaining: `{}`)",
34 truncate_long!(input.as_ref()),
35 any::type_name::<Self>(),
36 truncate_long!(value),
37 )));
38 }
39 Ok(result)
40 }
41 fn extract(value: &mut &str) -> Result<Self>
42 where
43 Self: Sized,
44 {
45 Err(Error::msg(format!(
46 "Cannot parse '{value}' as {}",
47 any::type_name::<Self>()
48 )))
49 }
50}
51
52impl<T: AsValue> From<T> for Value {
53 fn from(value: T) -> Self {
54 value.as_value()
55 }
56}
57
58impl From<&'static str> for Value {
59 fn from(value: &'static str) -> Self {
60 Value::Varchar(Some(value.into()))
61 }
62}
63
64macro_rules! impl_as_value {
65 ($source:ty, $destination:path $(, $pat_rest:pat => $expr_rest:expr)* $(,)?) => {
66 impl AsValue for $source {
67 fn as_empty_value() -> Value {
68 $destination(None)
69 }
70 fn as_value(self) -> Value {
71 $destination(Some(self as _))
72 }
73 fn try_from_value(value: Value) -> Result<Self> {
74 match value {
75 $destination(Some(v), ..) => Ok(v as _),
76 $($pat_rest => $expr_rest,)*
77 #[allow(unreachable_patterns)]
78 Value::Int32(Some(v), ..) => {
79 if (v as i128).clamp(<$source>::MIN as _, <$source>::MAX as _) != v as i128 {
80 return Err(Error::msg(format!(
81 "Value {v}: i32 is out of range for {}",
82 any::type_name::<Self>(),
83 )));
84 }
85 Ok(v as $source)
86 },
87 #[allow(unreachable_patterns)]
88 Value::Int64(Some(v), ..) => {
89 if (v as i128).clamp(<$source>::MIN as _, <$source>::MAX as _) != v as i128 {
90 return Err(Error::msg(format!(
91 "Value {v}: i64 is out of range for {}",
92 any::type_name::<Self>(),
93 )));
94 }
95 Ok(v as $source)
96 }
97 Value::Unknown(Some(ref v), ..) => Self::parse(v),
98 _ => Err(Error::msg(format!(
99 "Cannot convert {value:?} to {}",
100 any::type_name::<Self>(),
101 ))),
102 }
103 }
104 fn extract(input: &mut &str) -> Result<Self> {
105 if input.is_empty() {
106 return Err(Error::msg(format!(
107 "Cannot extract {} from empty string",
108 any::type_name::<Self>(),
109 )));
110 }
111 let mut value = *input;
112 macro_rules! do_extract {
113 ($parse:expr) => {{
114 let (num, tail) = $parse();
115 if tail > 0 {
116 let min = <$source>::MIN;
117 let max = <$source>::MAX;
118 if num < min as _ || num > max as _ {
119 return Err(Error::msg(format!(
120 "Parsed integer {} is out of range for {}",
121 value,
122 any::type_name::<Self>(),
123 )))
124 }
125 value = &value[tail..];
126 *input = value;
127 return Ok(num as _);
128 }
129 }
130 }}
131 let mut v = value;
132 let is_negative = value.starts_with('-');
133 let first = if is_negative {
134 v = &v[1..];
135 1
136 } else {
137 0
138 };
139 let v = &value[first..v.chars().take_while(char::is_ascii_digit).count()];
140 #[allow(unused_comparisons)]
141 let is_signed = <$source>::MIN < 0;
142 let lim = if is_negative {
143 "170141183460469231731687303715884105728"
144 } else if is_signed {
145 "170141183460469231731687303715884105727"
146 } else {
147 "340282366920938463463374607431768211455"
148 };
149 if v.len() > lim.len() || v.len() == lim.len() && v > lim {
151 return Err(Error::msg(format!(
152 "Value {value} is out of range for {}",
153 any::type_name::<Self>(),
154 )));
155 }
156 if is_signed {
157 do_extract!(|| i128::from_radix_10_signed(value.as_bytes()));
158 } else {
159 do_extract!(|| u128::from_radix_10(value.as_bytes()));
160 }
161 Err(Error::msg(format!(
162 "Cannot extract {} from `{value}`",
163 any::type_name::<Self>(),
164 )))
165 }
166 }
167 };
168}
169impl_as_value!(
170 i8,
171 Value::Int8,
172 Value::UInt8(Some(v), ..) => Ok(v as _),
173 Value::Int16(Some(v), ..) => {
174 let result = v as i8;
175 if result as i16 != v {
176 return Err(Error::msg(format!("Value {v}: i16 is out of range for i8")));
177 }
178 Ok(result)
179 },
180);
181impl_as_value!(
182 i16,
183 Value::Int16,
184 Value::Int8(Some(v), ..) => Ok(v as _),
185 Value::UInt16(Some(v), ..) => Ok(v as _),
186 Value::UInt8(Some(v), ..) => Ok(v as _),
187);
188impl_as_value!(
189 i32,
190 Value::Int32,
191 Value::Int16(Some(v), ..) => Ok(v as _),
192 Value::Int8(Some(v), ..) => Ok(v as _),
193 Value::UInt32(Some(v), ..) => Ok(v as _),
194 Value::UInt16(Some(v), ..) => Ok(v as _),
195 Value::UInt8(Some(v), ..) => Ok(v as _),
196 Value::Decimal(Some(v), ..) => {
197 let error = Error::msg(format!("Value {v}: Decimal does not fit into i32"));
198 if !v.is_integer() {
199 return Err(error.context("The value is not a integer"));
200 }
201 v.to_i32().ok_or(error)
202 }
203);
204impl_as_value!(
205 i64,
206 Value::Int64,
207 Value::Int32(Some(v), ..) => Ok(v as _),
208 Value::Int16(Some(v), ..) => Ok(v as _),
209 Value::Int8(Some(v), ..) => Ok(v as _),
210 Value::UInt64(Some(v), ..) => Ok(v as _),
211 Value::UInt32(Some(v), ..) => Ok(v as _),
212 Value::UInt16(Some(v), ..) => Ok(v as _),
213 Value::UInt8(Some(v), ..) => Ok(v as _),
214 Value::Decimal(Some(v), ..) => {
215 let error = Error::msg(format!("Value {v}: Decimal does not fit into i64"));
216 if !v.is_integer() {
217 return Err(error.context("The value is not a integer"));
218 }
219 v.to_i64().ok_or(error)
220 }
221);
222impl_as_value!(
223 i128,
224 Value::Int128,
225 Value::Int64(Some(v), ..) => Ok(v as _),
226 Value::Int32(Some(v), ..) => Ok(v as _),
227 Value::Int16(Some(v), ..) => Ok(v as _),
228 Value::Int8(Some(v), ..) => Ok(v as _),
229 Value::UInt128(Some(v), ..) => Ok(v as _),
230 Value::UInt64(Some(v), ..) => Ok(v as _),
231 Value::UInt32(Some(v), ..) => Ok(v as _),
232 Value::UInt16(Some(v), ..) => Ok(v as _),
233 Value::UInt8(Some(v), ..) => Ok(v as _),
234 Value::Decimal(Some(v), ..) => {
235 let error = Error::msg(format!("Value {v}: Decimal does not fit into i128"));
236 if !v.is_integer() {
237 return Err(error.context("The value is not a integer"));
238 }
239 v.to_i128().ok_or(error)
240 }
241);
242impl_as_value!(
243 isize,
244 Value::Int64,
245 Value::Int32(Some(v), ..) => Ok(v as _),
246 Value::Int16(Some(v), ..) => Ok(v as _),
247 Value::Int8(Some(v), ..) => Ok(v as _),
248 Value::UInt64(Some(v), ..) => Ok(v as _),
249 Value::UInt32(Some(v), ..) => Ok(v as _),
250 Value::UInt16(Some(v), ..) => Ok(v as _),
251 Value::UInt8(Some(v), ..) => Ok(v as _),
252 Value::Decimal(Some(v), ..) => {
253 let error = Error::msg(format!("Value {v}: Decimal does not fit into i64"));
254 if !v.is_integer() {
255 return Err(error.context("The value is not a integer"));
256 }
257 v.to_isize().ok_or(error)
258 }
259);
260impl_as_value!(
261 u8,
262 Value::UInt8,
263 Value::Int16(Some(v), ..) => {
264 v.to_u8().ok_or(Error::msg(format!("Value {v}: i16 is out of range for u8")))
265 }
266);
267impl_as_value!(
268 u16,
269 Value::UInt16,
270 Value::UInt8(Some(v), ..) => Ok(v as _),
271 Value::Int32(Some(v), ..) => {
272 let result = v as u16;
273 if result as i32 != v {
274 return Err(Error::msg(format!("Value {v}: i32 is out of range for u16")));
275 }
276 Ok(result)
277 }
278);
279impl_as_value!(
280 u32,
281 Value::UInt32,
282 Value::UInt16(Some(v), ..) => Ok(v as _),
283 Value::UInt8(Some(v), ..) => Ok(v as _),
284);
285impl_as_value!(
286 u64,
287 Value::UInt64,
288 Value::UInt32(Some(v), ..) => Ok(v as _),
289 Value::UInt16(Some(v), ..) => Ok(v as _),
290 Value::UInt8(Some(v), ..) => Ok(v as _),
291 Value::Decimal(Some(v), ..) => {
292 let error = Error::msg(format!("Value {v}: Decimal does not fit into u64"));
293 if !v.is_integer() {
294 return Err(error.context("The value is not a integer"));
295 }
296 v.to_u64().ok_or(error)
297 }
298);
299impl_as_value!(
300 u128,
301 Value::UInt128,
302 Value::UInt64(Some(v), ..) => Ok(v as _),
303 Value::UInt32(Some(v), ..) => Ok(v as _),
304 Value::UInt16(Some(v), ..) => Ok(v as _),
305 Value::UInt8(Some(v), ..) => Ok(v as _),
306 Value::Decimal(Some(v), ..) => {
307 let error = Error::msg(format!("Value {v}: Decimal does not fit into u128"));
308 if !v.is_integer() {
309 return Err(error.context("The value is not a integer"));
310 }
311 v.to_u128().ok_or(error)
312 }
313);
314impl_as_value!(
315 usize,
316 Value::UInt64,
317 Value::UInt32(Some(v), ..) => Ok(v as _),
318 Value::UInt16(Some(v), ..) => Ok(v as _),
319 Value::UInt8(Some(v), ..) => Ok(v as _),
320 Value::Decimal(Some(v), ..) => {
321 let error = Error::msg(format!("Value {v}: Decimal does not fit into u64"));
322 if !v.is_integer() {
323 return Err(error.context("The value is not a integer"));
324 }
325 v.to_usize().ok_or(error)
326 }
327);
328
329macro_rules! impl_as_value {
330 ($source:ty, $destination:path, $extract:expr $(, $pat_rest:pat => $expr_rest:expr)* $(,)?) => {
331 impl AsValue for $source {
332 fn as_empty_value() -> Value {
333 $destination(None)
334 }
335 fn as_value(self) -> Value {
336 $destination(Some(self.into()))
337 }
338 fn try_from_value(value: Value) -> Result<Self> {
339 match value {
340 $destination(Some(v), ..) => Ok(v.into()),
341 $($pat_rest => $expr_rest,)*
342 #[allow(unreachable_patterns)]
343 Value::Unknown(Some(ref v)) => <Self as AsValue>::parse(v),
344 _ => Err(Error::msg(format!(
345 "Cannot convert {value:?} to {}",
346 any::type_name::<Self>(),
347 ))),
348 }
349 }
350 fn extract(value: &mut &str) -> Result<Self> {
351 $extract(value)
352 }
353 }
354 };
355}
356impl_as_value!(
357 bool,
358 Value::Boolean,
359 |input: &mut &str| {
360 let mut value = *input;
361 let result = consume_while(&mut value, |v| v.is_alphabetic() || *v == '_');
362 let result = match result {
363 x if x.eq_ignore_ascii_case("true") || x.eq_ignore_ascii_case("t") => Ok(true),
364 x if x.eq_ignore_ascii_case("false") || x.eq_ignore_ascii_case("f") => Ok(false),
365 _ => return Err(Error::msg(format!("Cannot parse boolean from '{input}'")))
366 };
367 *input = value;
368 result
369 },
370 Value::Int8(Some(v), ..) => Ok(v != 0),
371 Value::Int16(Some(v), ..) => Ok(v != 0),
372 Value::Int32(Some(v), ..) => Ok(v != 0),
373 Value::Int64(Some(v), ..) => Ok(v != 0),
374 Value::Int128(Some(v), ..) => Ok(v != 0),
375 Value::UInt8(Some(v), ..) => Ok(v != 0),
376 Value::UInt16(Some(v), ..) => Ok(v != 0),
377 Value::UInt32(Some(v), ..) => Ok(v != 0),
378 Value::UInt64(Some(v), ..) => Ok(v != 0),
379 Value::UInt128(Some(v), ..) => Ok(v != 0),
380);
381impl_as_value!(
382 f32,
383 Value::Float32,
384 |v: &mut &str| {
385 let (num, tail) = parse_partial(*v)?;
386 *v = &v[tail..];
387 Ok(num)
388 },
389 Value::Float64(Some(v), ..) => Ok(v as _),
390 Value::Decimal(Some(v), ..) => Ok(v.try_into()?),
391);
392impl_as_value!(
393 f64,
394 Value::Float64,
395 |v: &mut &str| {
396 let (num, tail) = parse_partial(*v)?;
397 *v = &v[tail..];
398 Ok(num)
399 },
400 Value::Float32(Some(v), ..) => Ok(v as _),
401 Value::Decimal(Some(v), ..) => Ok(v.try_into()?),
402);
403impl_as_value!(
404 char,
405 Value::Char,
406 |v: &mut &str| {
407 let result = v.chars().next().ok_or(Error::msg("Empty input"))?;
408 *v = &v[1..];
409 Ok(result)
410 },
411 Value::Varchar(Some(v), ..) => {
412 if v.len() != 1 {
413 return Err(Error::msg("Cannot convert Value::Varchar containing more then one character into a char"))
414 }
415 Ok(v.chars().next().unwrap())
416 }
417);
418impl_as_value!(
419 String,
420 Value::Varchar,
421 |input: &mut &str| {
422 let mut value = *input;
423 let delimiter = value.chars().next();
424 let delimiter = match delimiter {
425 Some('\'') | Some('"') => {
426 value = &value[1..];
427 delimiter
428 },
429 _ => None,
430 };
431 let mut result = String::new();
432 let mut chars = value.chars().peekable();
433 let mut pos = 0;
434 while let Some(c) = chars.next() {
435 if Some(c) == delimiter {
436 if let Some(next_c) = chars.peek()
437 && Some(*next_c) == delimiter {
438 result.push_str(&value[..=pos]);
439 value = &value[(pos + 2)..];
440 pos = 0;
441 chars.next();
442 continue;
443 }
444 result.push_str(&value[..pos]);
445 value = &value[(pos + 1)..];
446 *input = &value;
447 return Ok(result);
448 }
449 pos += 1;
450 }
451 if delimiter.is_some() {
452 result = format!("{}{}", delimiter.unwrap(), result);
453 }
454 result.push_str(&value[..pos]);
455 value = &value[pos..];
456 *input = value;
457 Ok(result)
458 },
459 Value::Char(Some(v), ..) => Ok(v.into()),
460);
461impl_as_value!(Box<[u8]>, Value::Blob, |input: &mut &str| {
462 let mut value = *input;
463 if value[0..2].eq_ignore_ascii_case("\\x") {
464 value = &value[2..];
465 }
466 let hex = consume_while(
467 &mut value,
468 |v| matches!(*v, '0'..='9' | 'a'..='f' | 'A'..='F'),
469 );
470 let result = hex::decode(hex).map(Into::into).context(format!(
471 "While decoding `{}` as {}",
472 truncate_long!(input),
473 any::type_name::<Self>()
474 ))?;
475 *input = value;
476 Ok(result)
477});
478impl_as_value!(Interval, Value::Interval, |input: &mut &str| {
479 let error = || {
480 Err(Error::msg(format!(
481 "Cannot extract interval from '{input}'"
482 )))
483 };
484 let mut value = *input;
485 let boundary = match value.chars().next() {
486 Some(v) if v == '"' || v == '\'' => {
487 value = &value[1..];
488 Some(v)
489 }
490 _ => None,
491 };
492 let mut interval = Interval::ZERO;
493 loop {
494 let mut cur = value;
495 let Ok(count) = i128::extract(&mut cur) else {
496 break;
497 };
498 cur = cur.trim_start();
499 let unit = consume_while(&mut cur, char::is_ascii_alphabetic);
500 if unit.is_empty() {
501 break;
502 }
503 match unit {
504 x if x.eq_ignore_ascii_case("y")
505 || x.eq_ignore_ascii_case("year")
506 || x.eq_ignore_ascii_case("years") =>
507 {
508 interval += Interval::from_years(count as _)
509 }
510 x if x.eq_ignore_ascii_case("mon")
511 || x.eq_ignore_ascii_case("mons")
512 || x.eq_ignore_ascii_case("month")
513 || x.eq_ignore_ascii_case("months") =>
514 {
515 interval += Interval::from_months(count as _)
516 }
517 x if x.eq_ignore_ascii_case("d")
518 || x.eq_ignore_ascii_case("day")
519 || x.eq_ignore_ascii_case("days") =>
520 {
521 interval += Interval::from_days(count as _)
522 }
523 x if x.eq_ignore_ascii_case("h")
524 || x.eq_ignore_ascii_case("hour")
525 || x.eq_ignore_ascii_case("hours") =>
526 {
527 interval += Interval::from_hours(count as _)
528 }
529 x if x.eq_ignore_ascii_case("min")
530 || x.eq_ignore_ascii_case("mins")
531 || x.eq_ignore_ascii_case("minute")
532 || x.eq_ignore_ascii_case("minutes") =>
533 {
534 interval += Interval::from_mins(count as _)
535 }
536 x if x.eq_ignore_ascii_case("s")
537 || x.eq_ignore_ascii_case("sec")
538 || x.eq_ignore_ascii_case("secs")
539 || x.eq_ignore_ascii_case("second")
540 || x.eq_ignore_ascii_case("seconds") =>
541 {
542 interval += Interval::from_secs(count as _)
543 }
544 x if x.eq_ignore_ascii_case("micro")
545 || x.eq_ignore_ascii_case("micros")
546 || x.eq_ignore_ascii_case("microsecond")
547 || x.eq_ignore_ascii_case("microseconds") =>
548 {
549 interval += Interval::from_micros(count as _)
550 }
551 x if x.eq_ignore_ascii_case("ns")
552 || x.eq_ignore_ascii_case("nano")
553 || x.eq_ignore_ascii_case("nanos")
554 || x.eq_ignore_ascii_case("nanosecond")
555 || x.eq_ignore_ascii_case("nanoseconds") =>
556 {
557 interval += Interval::from_nanos(count as _)
558 }
559 _ => return error(),
560 }
561 value = cur.trim_start();
562 }
563 let neg = if Some('-') == value.chars().next() {
564 value = value[1..].trim_ascii_start();
565 true
566 } else {
567 false
568 };
569 let mut time_interval = Interval::ZERO;
570 let (num, tail) = u64::from_radix_10(value.as_bytes());
571 if tail > 0 {
572 time_interval += Interval::from_hours(num as _);
573 value = &value[tail..];
574 if Some(':') == value.chars().next() {
575 value = &value[1..];
576 let (num, tail) = u64::from_radix_10(value.as_bytes());
577 if tail == 0 {
578 return error();
579 }
580 value = &value[tail..];
581 time_interval += Interval::from_mins(num as _);
582 if Some(':') == value.chars().next() {
583 value = &value[1..];
584 let (num, tail) = u64::from_radix_10(value.as_bytes());
585 if tail == 0 {
586 return error();
587 }
588 value = &value[tail..];
589 time_interval += Interval::from_secs(num as _);
590 if Some('.') == value.chars().next() {
591 value = &value[1..];
592 let (mut num, mut tail) = i128::from_radix_10(value.as_bytes());
593 if tail == 0 {
594 return error();
595 }
596 value = &value[tail..];
597 tail -= 1;
598 let magnitude = tail / 3;
599 num *= 10_i128.pow(2 - tail as u32 % 3);
600 match magnitude {
601 0 => time_interval += Interval::from_millis(num),
602 1 => time_interval += Interval::from_micros(num),
603 2 => time_interval += Interval::from_nanos(num),
604 _ => return error(),
605 }
606 }
607 }
608 }
609 if neg {
610 interval -= time_interval;
611 } else {
612 interval += time_interval;
613 }
614 }
615 if let Some(b) = boundary {
616 if value.chars().next() != Some(b) {
617 return error();
618 }
619 value = value[1..].trim_ascii_start();
620 }
621 *input = value;
622 Ok(interval)
623});
624impl_as_value!(std::time::Duration, Value::Interval, |v| {
625 <Interval as AsValue>::extract(v).map(Into::into)
626});
627impl_as_value!(time::Duration, Value::Interval, |v| {
628 <Interval as AsValue>::extract(v).map(Into::into)
629});
630impl_as_value!(
631 Uuid,
632 Value::Uuid,
633 |v: &mut &str| {
634 let result = Ok(Uuid::parse_str(&v[0..36])?);
635 *v = &v[36..];
636 result
637 },
638 Value::Varchar(Some(v), ..) => Self::parse(v),
639);
640
641macro_rules! parse_time {
642 ($value: ident, $($formats:literal),+ $(,)?) => {
643 'value: {
644 for format in [$($formats,)+] {
645 let format = parse_borrowed::<2>(format)?;
646 let mut parsed = time::parsing::Parsed::new();
647 let remaining = parsed.parse_items($value.as_bytes(), &format);
648 if let Ok(remaining) = remaining {
649 let result = parsed.try_into()?;
650 *$value = &$value[($value.len() - remaining.len())..];
651 break 'value Ok(result);
652 }
653 }
654 Err(Error::msg(format!(
655 "Cannot extract from `{}` as {}",
656 $value,
657 any::type_name::<Self>()
658 )))
659 }
660 }
661}
662
663impl_as_value!(
664 time::Date,
665 Value::Date,
666 |v: &mut &str| {
667 let mut result: time::Date = parse_time!(v, "[year]-[month]-[day]")?;
668 {
669 let mut attempt = v.trim_start();
670 let suffix = consume_while(&mut attempt, char::is_ascii_alphabetic);
671 if suffix.eq_ignore_ascii_case("bc") {
672 *v = attempt;
673 result =
674 time::Date::from_calendar_date(-(result.year() - 1), result.month(), result.day())?;
675 *v = attempt
676 }
677 if suffix.eq_ignore_ascii_case("ad") {
678 *v = attempt
679 }
680 }
681 Ok(result)
682 },
683 Value::Varchar(Some(v), ..) => <Self as AsValue>::parse(v),
684);
685
686impl_as_value!(
687 time::Time,
688 Value::Time,
689 |v: &mut &str| {
690 let result: time::Time = parse_time!(
691 v,
692 "[hour]:[minute]:[second].[subsecond]",
693 "[hour]:[minute]:[second]",
694 "[hour]:[minute]",
695 )?;
696 Ok(result)
697 },
698 Value::Varchar(Some(v), ..) => <Self as AsValue>::parse(v),
699);
700
701impl_as_value!(
702 time::PrimitiveDateTime,
703 Value::Timestamp,
704 |v: &mut &str| {
705 let result: time::PrimitiveDateTime = parse_time!(
706 v,
707 "[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond]",
708 "[year]-[month]-[day]T[hour]:[minute]:[second]",
709 "[year]-[month]-[day]T[hour]:[minute]",
710 "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]",
711 "[year]-[month]-[day] [hour]:[minute]:[second]",
712 "[year]-[month]-[day] [hour]:[minute]",
713 )?;
714 Ok(result)
715 },
716 Value::Varchar(Some(v), ..) => <Self as AsValue>::parse(v),
717);
718
719impl_as_value!(
720 time::OffsetDateTime,
721 Value::TimestampWithTimezone,
722 |v: &mut &str| {
723 let result: time::OffsetDateTime = parse_time!(
724 v,
725 "[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]:[offset_minute]",
726 "[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]",
727 "[year]-[month]-[day]T[hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]",
728 "[year]-[month]-[day]T[hour]:[minute]:[second][offset_hour sign:mandatory]",
729 "[year]-[month]-[day]T[hour]:[minute][offset_hour sign:mandatory]:[offset_minute]",
730 "[year]-[month]-[day]T[hour]:[minute][offset_hour sign:mandatory]",
731 "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]:[offset_minute]",
732 "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]",
733 "[year]-[month]-[day] [hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]",
734 "[year]-[month]-[day] [hour]:[minute]:[second][offset_hour sign:mandatory]",
735 "[year]-[month]-[day] [hour]:[minute][offset_hour sign:mandatory]:[offset_minute]",
736 "[year]-[month]-[day] [hour]:[minute][offset_hour sign:mandatory]",
737 ).or(<PrimitiveDateTime as AsValue>::extract(v).map(|v| v.assume_utc()))?;
738 Ok(result)
739 },
740 Value::Timestamp(Some(timestamp), ..) => Ok(timestamp.assume_utc()),
741 Value::Varchar(Some(v), ..) => <Self as AsValue>::parse(v),
742);
743
744impl AsValue for Decimal {
745 fn as_empty_value() -> Value {
746 Value::Decimal(None, 0, 0)
747 }
748 fn as_value(self) -> Value {
749 Value::Decimal(Some(self), 0, self.scale() as _)
750 }
751 fn try_from_value(value: Value) -> Result<Self> {
752 match value {
753 Value::Decimal(Some(v), ..) => Ok(v),
754 Value::Int8(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
755 Value::Int16(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
756 Value::Int32(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
757 Value::Int64(Some(v), ..) => Ok(Decimal::new(v, 0)),
758 Value::UInt8(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
759 Value::UInt16(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
760 Value::UInt32(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
761 Value::UInt64(Some(v), ..) => Ok(Decimal::new(v as i64, 0)),
762 Value::Float32(Some(v), ..) => Ok(Decimal::from_f32(v)
763 .ok_or(Error::msg(format!("Cannot convert {value:?} to Decimal")))?),
764 Value::Float64(Some(v), ..) => Ok(Decimal::from_f64(v)
765 .ok_or(Error::msg(format!("Cannot convert {value:?} to Decimal")))?),
766 Value::Unknown(Some(v), ..) => Self::parse(&v),
767 _ => Err(Error::msg(format!("Cannot convert {value:?} to Decimal"))),
768 }
769 }
770 fn extract(input: &mut &str) -> Result<Self> {
771 let mut value = *input;
772 let (mut n, len) = i128::from_radix_10_signed(value.as_bytes());
773 value = &value[len..];
774 let n = if value.chars().next() == Some('.') {
775 value = &value[1..];
776 let (dec, len) = i128::from_radix_10(value.as_bytes());
777 n = n * 10u64.pow(len as _) as i128 + dec;
778 value = &value[len..];
779 Decimal::try_from_i128_with_scale(n, len as _)
780 .map_err(|_| Error::msg(format!("Could not create a Decimal from {n}")))
781 } else {
782 Decimal::from_i128(n)
783 .ok_or_else(|| Error::msg(format!("Could not create a Decimal from {n}")))
784 }?;
785 *input = value.trim_ascii_start();
786 Ok(n)
787 }
788}
789
790impl<const W: u8, const S: u8> AsValue for FixedDecimal<W, S> {
791 fn as_empty_value() -> Value {
792 Decimal::as_empty_value()
793 }
794 fn as_value(self) -> Value {
795 Value::Decimal(Some(self.0), W, S)
796 }
797 fn try_from_value(value: Value) -> Result<Self>
798 where
799 Self: Sized,
800 {
801 Ok(Self(Decimal::try_from_value(value)?))
802 }
803}
804
805impl<T: AsValue, const N: usize> AsValue for [T; N] {
806 fn as_empty_value() -> Value {
807 Value::Array(None, Box::new(T::as_empty_value()), N as u32)
808 }
809 fn as_value(self) -> Value {
810 Value::Array(
811 Some(self.into_iter().map(AsValue::as_value).collect()),
812 Box::new(T::as_empty_value()),
813 N as u32,
814 )
815 }
816 fn try_from_value(value: Value) -> Result<Self> {
817 let convert_iter = |iter: Vec<Value>| -> Result<[T; N]> {
818 iter.into_iter()
819 .map(T::try_from_value)
820 .collect::<Result<Vec<_>>>()?
821 .try_into()
822 .map_err(|v: Vec<T>| {
823 Error::msg(format!(
824 "Expected array of length {}, got {} elements ({})",
825 N,
826 v.len(),
827 any::type_name::<[T; N]>()
828 ))
829 })
830 };
831 match value {
832 Value::List(Some(v), ..) if v.len() == N => convert_iter(v),
833 Value::Array(Some(v), ..) if v.len() == N => convert_iter(v.into()),
834 Value::Unknown(Some(v)) => Self::parse(v),
835 _ => Err(Error::msg(format!(
836 "Cannot convert {value:?} to array {}",
837 any::type_name::<Self>()
838 ))),
839 }
840 }
841 fn extract(input: &mut &str) -> Result<Self> {
842 let mut value = *input;
843 let error = Arc::new(format!(
844 "Cannot extract `{}` as array {}",
845 truncate_long!(value),
846 any::type_name::<Self>(),
847 ));
848 let closing = match value.chars().next() {
849 Some('{') => '}',
850 Some('[') => ']',
851 _ => {
852 return Err(Error::msg(error));
853 }
854 };
855 value = &value[1..].trim_ascii_start();
856 let mut result = array::from_fn(|i| {
858 let result = T::extract(&mut value)?;
859 value = value.trim_ascii_start();
860 match value.chars().next() {
861 Some(',') => value = &value[1..].trim_ascii_start(),
862 _ if i != N - 1 => {
863 return Err(Error::msg(error.clone()));
864 }
865 _ => {}
866 }
867 Ok(result)
868 });
869 if let Some(error) = result.iter_mut().find_map(|v| {
870 if let Err(e) = v {
871 let mut r = Error::msg("");
872 mem::swap(e, &mut r);
873 Some(r)
874 } else {
875 None
876 }
877 }) {
878 return Err(error);
879 }
880 if Some(closing) != value.chars().next() {
881 return Err(Error::msg(format!(
882 "Incorrect array `{}`, expected a `{}`",
883 truncate_long!(value),
884 closing
885 )));
886 };
887 value = &value[1..].trim_ascii_start();
888 *input = &value;
889 Ok(result.map(Result::unwrap))
890 }
891}
892
893macro_rules! impl_as_value {
894 ($list:ident) => {
895 impl<T: AsValue> AsValue for $list<T> {
896 fn as_empty_value() -> Value {
897 Value::List(None, Box::new(T::as_empty_value()))
898 }
899 fn as_value(self) -> Value {
900 Value::List(
901 Some(self.into_iter().map(AsValue::as_value).collect()),
902 Box::new(T::as_empty_value()),
903 )
904 }
905 fn try_from_value(value: Value) -> Result<Self> {
906 match value {
907 Value::List(Some(v), ..) => Ok(v
908 .into_iter()
909 .map(|v| Ok::<_, Error>(<T as AsValue>::try_from_value(v)?))
910 .collect::<Result<_>>()?),
911 Value::List(None, ..) => Ok($list::<T>::new()),
912 Value::Array(Some(v), ..) => Ok(v
913 .into_iter()
914 .map(|v| Ok::<_, Error>(<T as AsValue>::try_from_value(v)?))
915 .collect::<Result<_>>()?),
916 _ => Err(Error::msg(format!(
917 "Cannot convert {value:?} to {}",
918 any::type_name::<Self>(),
919 ))),
920 }
921 }
922 }
923 };
924}
925impl_as_value!(Vec);
926impl_as_value!(VecDeque);
927impl_as_value!(LinkedList);
928
929macro_rules! impl_as_value {
930 ($map:ident, $($key_trait:ident),+) => {
931 impl<K: AsValue $(+ $key_trait)+, V: AsValue> AsValue for $map<K, V> {
932 fn as_empty_value() -> Value {
933 Value::Map(None, K::as_empty_value().into(), V::as_empty_value().into())
934 }
935 fn as_value(self) -> Value {
936 Value::Map(
937 Some(
938 self.into_iter()
939 .map(|(k, v)| (k.as_value(), v.as_value()))
940 .collect(),
941 ),
942 K::as_empty_value().into(),
943 V::as_empty_value().into(),
944 )
945 }
946 fn try_from_value(value: Value) -> Result<Self> {
947 if let Value::Map(Some(v), ..) = value {
948 Ok(v.into_iter()
949 .map(|(k, v)| {
950 Ok((
951 <K as AsValue>::try_from_value(k)?,
952 <V as AsValue>::try_from_value(v)?,
953 ))
954 })
955 .collect::<Result<_>>()?)
956 } else {
957 Err(Error::msg(format!(
958 "Cannot convert {value:?} to {}",
959 any::type_name::<Self>(),
960 )))
961 }
962 }
963 }
964 }
965}
966impl_as_value!(BTreeMap, Ord);
967impl_as_value!(HashMap, Eq, Hash);
968
969impl<'a> AsValue for Cow<'a, str> {
970 fn as_empty_value() -> Value {
971 Value::Varchar(None)
972 }
973 fn as_value(self) -> Value {
974 Value::Varchar(Some(self.into()))
975 }
976 fn try_from_value(value: Value) -> Result<Self>
977 where
978 Self: Sized,
979 {
980 String::try_from_value(value).map(Into::into)
981 }
982}
983
984impl<T: AsValue> AsValue for Passive<T> {
985 fn as_empty_value() -> Value {
986 T::as_empty_value()
987 }
988 fn as_value(self) -> Value {
989 match self {
990 Passive::Set(v) => v.as_value(),
991 Passive::NotSet => T::as_empty_value(),
992 }
993 }
994 fn try_from_value(value: Value) -> Result<Self> {
995 Ok(Passive::Set(<T as AsValue>::try_from_value(value)?))
996 }
997}
998
999impl<T: AsValue> AsValue for Option<T> {
1000 fn as_empty_value() -> Value {
1001 T::as_empty_value()
1002 }
1003 fn as_value(self) -> Value {
1004 match self {
1005 Some(v) => v.as_value(),
1006 None => T::as_empty_value(),
1007 }
1008 }
1009 fn try_from_value(value: Value) -> Result<Self> {
1010 Ok(if value.is_null() {
1011 None
1012 } else {
1013 Some(<T as AsValue>::try_from_value(value)?)
1014 })
1015 }
1016 fn extract(value: &mut &str) -> Result<Self>
1017 where
1018 Self: Sized,
1019 {
1020 T::extract(value).map(Some)
1021 }
1022}
1023
1024impl<T: AsValue> AsValue for Box<T> {
1026 fn as_empty_value() -> Value {
1027 T::as_empty_value()
1028 }
1029 fn as_value(self) -> Value {
1030 (*self).as_value()
1031 }
1032 fn try_from_value(value: Value) -> Result<Self> {
1033 Ok(Box::new(<T as AsValue>::try_from_value(value)?))
1034 }
1035 fn extract(value: &mut &str) -> Result<Self>
1036 where
1037 Self: Sized,
1038 {
1039 T::extract(value).map(Box::new)
1040 }
1041}
1042
1043macro_rules! impl_as_value {
1044 ($wrapper:ident) => {
1045 impl<T: AsValue + ToOwned<Owned = impl AsValue>> AsValue for $wrapper<T> {
1046 fn as_empty_value() -> Value {
1047 T::as_empty_value()
1048 }
1049 fn as_value(self) -> Value {
1050 $wrapper::<T>::into_inner(self).as_value()
1051 }
1052 fn try_from_value(value: Value) -> Result<Self> {
1053 Ok($wrapper::new(<T as AsValue>::try_from_value(value)?))
1054 }
1055 }
1056 };
1057}
1058impl_as_value!(Cell);
1060impl_as_value!(RefCell);
1061
1062impl<T: AsValue> AsValue for RwLock<T> {
1063 fn as_empty_value() -> Value {
1064 T::as_empty_value()
1065 }
1066 fn as_value(self) -> Value {
1067 self.into_inner()
1068 .expect("Error occurred while trying to take the content of the RwLock")
1069 .as_value()
1070 }
1071 fn try_from_value(value: Value) -> Result<Self> {
1072 Ok(RwLock::new(<T as AsValue>::try_from_value(value)?))
1073 }
1074}
1075
1076macro_rules! impl_as_value {
1077 ($wrapper:ident) => {
1078 impl<T: AsValue + ToOwned<Owned = impl AsValue>> AsValue for $wrapper<T> {
1079 fn as_empty_value() -> Value {
1080 T::as_empty_value()
1081 }
1082 fn as_value(self) -> Value {
1083 $wrapper::try_unwrap(self)
1084 .map(|v| v.as_value())
1085 .unwrap_or_else(|v| v.as_ref().to_owned().as_value())
1086 }
1087 fn try_from_value(value: Value) -> Result<Self> {
1088 Ok($wrapper::new(<T as AsValue>::try_from_value(value)?))
1089 }
1090 }
1091 };
1092}
1093impl_as_value!(Arc);
1094impl_as_value!(Rc);