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