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