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