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