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