1use crate::ast::*;
2use crate::error::{Error, ErrorKind};
3
4#[cfg(feature = "bigdecimal")]
5use bigdecimal::{BigDecimal, FromPrimitive, ToPrimitive};
6#[cfg(feature = "chrono")]
7use chrono::{DateTime, NaiveDate, NaiveTime, Utc};
8#[cfg(feature = "json")]
9use serde_json::{Number, Value as JsonValue};
10use std::{
11 borrow::{Borrow, Cow},
12 convert::TryFrom,
13 fmt,
14 str::FromStr,
15};
16#[cfg(feature = "uuid")]
17use uuid::Uuid;
18
19#[derive(Debug, Clone, PartialEq)]
21pub struct Raw<'a>(pub(crate) Value<'a>);
22
23pub trait IntoRaw<'a> {
27 fn raw(self) -> Raw<'a>;
28}
29
30impl<'a, T> IntoRaw<'a> for T
31where
32 T: Into<Value<'a>>,
33{
34 fn raw(self) -> Raw<'a> {
35 Raw(self.into())
36 }
37}
38
39#[derive(Debug, Clone, PartialEq)]
43pub enum Value<'a> {
44 Int32(Option<i32>),
46 Int64(Option<i64>),
48 Float(Option<f32>),
50 Double(Option<f64>),
52 Text(Option<Cow<'a, str>>),
54 Enum(Option<Cow<'a, str>>),
56 Bytes(Option<Cow<'a, [u8]>>),
58 Boolean(Option<bool>),
60 Char(Option<char>),
62 Array(Option<Vec<Value<'a>>>),
64 #[cfg(feature = "bigdecimal")]
66 Numeric(Option<BigDecimal>),
67 #[cfg(feature = "json")]
68 Json(Option<serde_json::Value>),
70 Xml(Option<Cow<'a, str>>),
72 #[cfg(feature = "uuid")]
73 Uuid(Option<Uuid>),
75 #[cfg(feature = "chrono")]
76 DateTime(Option<DateTime<Utc>>),
78 #[cfg(feature = "chrono")]
79 Date(Option<NaiveDate>),
81 #[cfg(feature = "chrono")]
82 Time(Option<NaiveTime>),
84}
85
86pub(crate) struct Params<'a>(pub(crate) &'a [Value<'a>]);
87
88impl<'a> fmt::Display for Params<'a> {
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 let len = self.0.len();
91
92 write!(f, "[")?;
93 for (i, val) in self.0.iter().enumerate() {
94 write!(f, "{val}")?;
95
96 if i < (len - 1) {
97 write!(f, ",")?;
98 }
99 }
100 write!(f, "]")
101 }
102}
103
104impl<'a> fmt::Display for Value<'a> {
105 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106 let res = match self {
107 Value::Int32(val) => val.map(|v| write!(f, "{v}")),
108 Value::Int64(val) => val.map(|v| write!(f, "{v}")),
109 Value::Float(val) => val.map(|v| write!(f, "{v}")),
110 Value::Double(val) => val.map(|v| write!(f, "{v}")),
111 Value::Text(val) => val.as_ref().map(|v| write!(f, "\"{v}\"")),
112 Value::Bytes(val) => val.as_ref().map(|v| write!(f, "<{} bytes blob>", v.len())),
113 Value::Enum(val) => val.as_ref().map(|v| write!(f, "\"{v}\"")),
114 Value::Boolean(val) => val.map(|v| write!(f, "{v}")),
115 Value::Char(val) => val.map(|v| write!(f, "'{v}'")),
116 Value::Array(vals) => vals.as_ref().map(|vals| {
117 let len = vals.len();
118
119 write!(f, "[")?;
120 for (i, val) in vals.iter().enumerate() {
121 write!(f, "{val}")?;
122
123 if i < (len - 1) {
124 write!(f, ",")?;
125 }
126 }
127 write!(f, "]")
128 }),
129 Value::Xml(val) => val.as_ref().map(|v| write!(f, "{v}")),
130 #[cfg(feature = "bigdecimal")]
131 Value::Numeric(val) => val.as_ref().map(|v| write!(f, "{v}")),
132 #[cfg(feature = "json")]
133 Value::Json(val) => val.as_ref().map(|v| write!(f, "{v}")),
134 #[cfg(feature = "uuid")]
135 Value::Uuid(val) => val.map(|v| write!(f, "\"{v}\"")),
136 #[cfg(feature = "chrono")]
137 Value::DateTime(val) => val.map(|v| write!(f, "\"{v}\"")),
138 #[cfg(feature = "chrono")]
139 Value::Date(val) => val.map(|v| write!(f, "\"{v}\"")),
140 #[cfg(feature = "chrono")]
141 Value::Time(val) => val.map(|v| write!(f, "\"{v}\"")),
142 };
143
144 match res {
145 Some(r) => r,
146 None => write!(f, "null"),
147 }
148 }
149}
150
151#[cfg(feature = "json")]
152impl<'a> From<Value<'a>> for serde_json::Value {
153 fn from(pv: Value<'a>) -> Self {
154 let res = match pv {
155 Value::Int32(i) => i.map(|i| serde_json::Value::Number(Number::from(i))),
156 Value::Int64(i) => i.map(|i| serde_json::Value::Number(Number::from(i))),
157 Value::Float(f) => f.map(|f| match Number::from_f64(f as f64) {
158 Some(number) => serde_json::Value::Number(number),
159 None => serde_json::Value::Null,
160 }),
161 Value::Double(f) => f.map(|f| match Number::from_f64(f) {
162 Some(number) => serde_json::Value::Number(number),
163 None => serde_json::Value::Null,
164 }),
165 Value::Text(cow) => cow.map(|cow| serde_json::Value::String(cow.into_owned())),
166 Value::Bytes(bytes) => bytes.map(|bytes| serde_json::Value::String(base64::encode(bytes))),
167 Value::Enum(cow) => cow.map(|cow| serde_json::Value::String(cow.into_owned())),
168 Value::Boolean(b) => b.map(serde_json::Value::Bool),
169 Value::Char(c) => c.map(|c| {
170 let bytes = [c as u8];
171 let s = std::str::from_utf8(&bytes)
172 .expect("interpret byte as UTF-8")
173 .to_string();
174 serde_json::Value::String(s)
175 }),
176 Value::Xml(cow) => cow.map(|cow| serde_json::Value::String(cow.into_owned())),
177 Value::Array(v) => {
178 v.map(|v| serde_json::Value::Array(v.into_iter().map(serde_json::Value::from).collect()))
179 }
180 #[cfg(feature = "bigdecimal")]
181 Value::Numeric(d) => d.map(|d| serde_json::to_value(d.to_f64().unwrap()).unwrap()),
182 #[cfg(feature = "json")]
183 Value::Json(v) => v,
184 #[cfg(feature = "uuid")]
185 Value::Uuid(u) => u.map(|u| serde_json::Value::String(u.hyphenated().to_string())),
186 #[cfg(feature = "chrono")]
187 Value::DateTime(dt) => dt.map(|dt| serde_json::Value::String(dt.to_rfc3339())),
188 #[cfg(feature = "chrono")]
189 Value::Date(date) => date.map(|date| serde_json::Value::String(format!("{date}"))),
190 #[cfg(feature = "chrono")]
191 Value::Time(time) => time.map(|time| serde_json::Value::String(format!("{time}"))),
192 };
193
194 match res {
195 Some(val) => val,
196 None => serde_json::Value::Null,
197 }
198 }
199}
200
201impl<'a> Value<'a> {
202 pub fn int32<I>(value: I) -> Self
204 where
205 I: Into<i32>,
206 {
207 Value::Int32(Some(value.into()))
208 }
209
210 pub fn int64<I>(value: I) -> Self
212 where
213 I: Into<i64>,
214 {
215 Value::Int64(Some(value.into()))
216 }
217
218 pub fn integer<I>(value: I) -> Self
220 where
221 I: Into<i32>,
222 {
223 Value::Int32(Some(value.into()))
224 }
225
226 #[cfg(feature = "bigdecimal")]
228 pub const fn numeric(value: BigDecimal) -> Self {
229 Value::Numeric(Some(value))
230 }
231
232 pub const fn float(value: f32) -> Self {
234 Self::Float(Some(value))
235 }
236
237 pub const fn double(value: f64) -> Self {
239 Self::Double(Some(value))
240 }
241
242 pub fn text<T>(value: T) -> Self
244 where
245 T: Into<Cow<'a, str>>,
246 {
247 Value::Text(Some(value.into()))
248 }
249
250 pub fn enum_variant<T>(value: T) -> Self
252 where
253 T: Into<Cow<'a, str>>,
254 {
255 Value::Enum(Some(value.into()))
256 }
257
258 pub fn bytes<B>(value: B) -> Self
260 where
261 B: Into<Cow<'a, [u8]>>,
262 {
263 Value::Bytes(Some(value.into()))
264 }
265
266 pub fn boolean<B>(value: B) -> Self
268 where
269 B: Into<bool>,
270 {
271 Value::Boolean(Some(value.into()))
272 }
273
274 pub fn character<C>(value: C) -> Self
276 where
277 C: Into<char>,
278 {
279 Value::Char(Some(value.into()))
280 }
281
282 pub fn array<I, V>(value: I) -> Self
284 where
285 I: IntoIterator<Item = V>,
286 V: Into<Value<'a>>,
287 {
288 Value::Array(Some(value.into_iter().map(|v| v.into()).collect()))
289 }
290
291 #[cfg(feature = "uuid")]
293 pub const fn uuid(value: Uuid) -> Self {
294 Value::Uuid(Some(value))
295 }
296
297 #[cfg(feature = "chrono")]
299 pub const fn datetime(value: DateTime<Utc>) -> Self {
300 Value::DateTime(Some(value))
301 }
302
303 #[cfg(feature = "chrono")]
305 pub const fn date(value: NaiveDate) -> Self {
306 Value::Date(Some(value))
307 }
308
309 #[cfg(feature = "chrono")]
311 pub const fn time(value: NaiveTime) -> Self {
312 Value::Time(Some(value))
313 }
314
315 #[cfg(feature = "json")]
317 pub const fn json(value: serde_json::Value) -> Self {
318 Value::Json(Some(value))
319 }
320
321 pub fn xml<T>(value: T) -> Self
323 where
324 T: Into<Cow<'a, str>>,
325 {
326 Value::Xml(Some(value.into()))
327 }
328
329 pub const fn is_null(&self) -> bool {
331 match self {
332 Value::Int32(i) => i.is_none(),
333 Value::Int64(i) => i.is_none(),
334 Value::Float(i) => i.is_none(),
335 Value::Double(i) => i.is_none(),
336 Value::Text(t) => t.is_none(),
337 Value::Enum(e) => e.is_none(),
338 Value::Bytes(b) => b.is_none(),
339 Value::Boolean(b) => b.is_none(),
340 Value::Char(c) => c.is_none(),
341 Value::Array(v) => v.is_none(),
342 Value::Xml(s) => s.is_none(),
343 #[cfg(feature = "bigdecimal")]
344 Value::Numeric(r) => r.is_none(),
345 #[cfg(feature = "uuid")]
346 Value::Uuid(u) => u.is_none(),
347 #[cfg(feature = "chrono")]
348 Value::DateTime(dt) => dt.is_none(),
349 #[cfg(feature = "chrono")]
350 Value::Date(d) => d.is_none(),
351 #[cfg(feature = "chrono")]
352 Value::Time(t) => t.is_none(),
353 #[cfg(feature = "json")]
354 Value::Json(json) => json.is_none(),
355 }
356 }
357
358 pub const fn is_text(&self) -> bool {
360 matches!(self, Value::Text(_))
361 }
362
363 pub fn as_str(&self) -> Option<&str> {
365 match self {
366 Value::Text(Some(cow)) => Some(cow.borrow()),
367 Value::Bytes(Some(cow)) => std::str::from_utf8(cow.as_ref()).ok(),
368 _ => None,
369 }
370 }
371
372 pub const fn as_char(&self) -> Option<char> {
374 match self {
375 Value::Char(c) => *c,
376 _ => None,
377 }
378 }
379
380 pub fn to_string(&self) -> Option<String> {
382 match self {
383 Value::Text(Some(cow)) => Some(cow.to_string()),
384 Value::Bytes(Some(cow)) => std::str::from_utf8(cow.as_ref()).map(|s| s.to_owned()).ok(),
385 _ => None,
386 }
387 }
388
389 pub fn into_string(self) -> Option<String> {
392 match self {
393 Value::Text(Some(cow)) => Some(cow.into_owned()),
394 Value::Bytes(Some(cow)) => String::from_utf8(cow.into_owned()).ok(),
395 _ => None,
396 }
397 }
398
399 pub const fn is_bytes(&self) -> bool {
401 matches!(self, Value::Bytes(_))
402 }
403
404 pub fn as_bytes(&self) -> Option<&[u8]> {
406 match self {
407 Value::Text(Some(cow)) => Some(cow.as_ref().as_bytes()),
408 Value::Bytes(Some(cow)) => Some(cow.as_ref()),
409 _ => None,
410 }
411 }
412
413 pub fn to_bytes(&self) -> Option<Vec<u8>> {
415 match self {
416 Value::Text(Some(cow)) => Some(cow.to_string().into_bytes()),
417 Value::Bytes(Some(cow)) => Some(cow.to_vec()),
418 _ => None,
419 }
420 }
421
422 pub const fn is_i32(&self) -> bool {
424 matches!(self, Value::Int32(_))
425 }
426
427 pub const fn is_i64(&self) -> bool {
429 matches!(self, Value::Int64(_))
430 }
431
432 pub const fn is_integer(&self) -> bool {
434 matches!(self, Value::Int32(_) | Value::Int64(_))
435 }
436
437 pub const fn as_i64(&self) -> Option<i64> {
439 match self {
440 Value::Int64(i) => *i,
441 _ => None,
442 }
443 }
444
445 pub const fn as_i32(&self) -> Option<i32> {
447 match self {
448 Value::Int32(i) => *i,
449 _ => None,
450 }
451 }
452
453 pub fn as_integer(&self) -> Option<i64> {
455 match self {
456 Value::Int32(i) => i.map(|i| i as i64),
457 Value::Int64(i) => *i,
458 _ => None,
459 }
460 }
461
462 pub const fn as_f64(&self) -> Option<f64> {
464 match self {
465 Value::Double(Some(f)) => Some(*f),
466 _ => None,
467 }
468 }
469
470 pub const fn as_f32(&self) -> Option<f32> {
472 match self {
473 Value::Float(Some(f)) => Some(*f),
474 _ => None,
475 }
476 }
477
478 #[cfg(feature = "bigdecimal")]
480 pub const fn is_numeric(&self) -> bool {
481 matches!(self, Value::Numeric(_) | Value::Float(_) | Value::Double(_))
482 }
483
484 #[cfg(feature = "bigdecimal")]
487 pub fn into_numeric(self) -> Option<BigDecimal> {
488 match self {
489 Value::Numeric(d) => d,
490 Value::Float(f) => f.and_then(BigDecimal::from_f32),
491 Value::Double(f) => f.and_then(BigDecimal::from_f64),
492 _ => None,
493 }
494 }
495
496 #[cfg(feature = "bigdecimal")]
499 pub const fn as_numeric(&self) -> Option<&BigDecimal> {
500 match self {
501 Value::Numeric(d) => d.as_ref(),
502 _ => None,
503 }
504 }
505
506 pub const fn is_bool(&self) -> bool {
508 match self {
509 Value::Boolean(_) => true,
510 Value::Int32(Some(i)) if *i == 0 || *i == 1 => true,
512 Value::Int64(Some(i)) if *i == 0 || *i == 1 => true,
513 _ => false,
514 }
515 }
516
517 pub const fn as_bool(&self) -> Option<bool> {
519 match self {
520 Value::Boolean(b) => *b,
521 Value::Int32(Some(i)) if *i == 0 || *i == 1 => Some(*i == 1),
523 Value::Int64(Some(i)) if *i == 0 || *i == 1 => Some(*i == 1),
524 _ => None,
525 }
526 }
527
528 pub const fn is_array(&self) -> bool {
530 matches!(self, Value::Array(_))
531 }
532
533 pub const fn as_array(&self) -> Option<&Vec<Value>> {
534 match self {
535 Value::Array(a) => a.as_ref(),
536 _ => None,
537 }
538 }
539
540 #[cfg(feature = "uuid")]
542 pub const fn is_uuid(&self) -> bool {
543 matches!(self, Value::Uuid(_))
544 }
545
546 #[cfg(feature = "uuid")]
548 pub const fn as_uuid(&self) -> Option<Uuid> {
549 match self {
550 Value::Uuid(u) => *u,
551 _ => None,
552 }
553 }
554
555 #[cfg(feature = "chrono")]
557 pub const fn is_datetime(&self) -> bool {
558 matches!(self, Value::DateTime(_))
559 }
560
561 #[cfg(feature = "chrono")]
563 pub const fn as_datetime(&self) -> Option<DateTime<Utc>> {
564 match self {
565 Value::DateTime(dt) => *dt,
566 _ => None,
567 }
568 }
569
570 #[cfg(feature = "chrono")]
572 pub const fn is_date(&self) -> bool {
573 matches!(self, Value::Date(_))
574 }
575
576 #[cfg(feature = "chrono")]
578 pub const fn as_date(&self) -> Option<NaiveDate> {
579 match self {
580 Value::Date(dt) => *dt,
581 _ => None,
582 }
583 }
584
585 #[cfg(feature = "chrono")]
587 pub const fn is_time(&self) -> bool {
588 matches!(self, Value::Time(_))
589 }
590
591 #[cfg(feature = "chrono")]
593 pub const fn as_time(&self) -> Option<NaiveTime> {
594 match self {
595 Value::Time(time) => *time,
596 _ => None,
597 }
598 }
599
600 #[cfg(feature = "json")]
602 pub const fn is_json(&self) -> bool {
603 matches!(self, Value::Json(_))
604 }
605
606 #[cfg(feature = "json")]
608 pub const fn as_json(&self) -> Option<&serde_json::Value> {
609 match self {
610 Value::Json(Some(j)) => Some(j),
611 _ => None,
612 }
613 }
614
615 #[cfg(feature = "json")]
617 pub fn into_json(self) -> Option<serde_json::Value> {
618 match self {
619 Value::Json(Some(j)) => Some(j),
620 _ => None,
621 }
622 }
623
624 pub fn into_vec<T>(self) -> Option<Vec<T>>
626 where
627 T: TryFrom<Value<'a>>,
629 {
630 match self {
631 Value::Array(Some(vec)) => {
632 let rslt: Result<Vec<_>, _> = vec.into_iter().map(T::try_from).collect();
633 match rslt {
634 Err(_) => None,
635 Ok(values) => Some(values),
636 }
637 }
638 _ => None,
639 }
640 }
641}
642
643value!(val: i64, Int64, val);
644value!(val: i32, Int32, val);
645value!(val: bool, Boolean, val);
646value!(val: &'a str, Text, val.into());
647value!(val: String, Text, val.into());
648value!(val: usize, Int64, i64::try_from(val).unwrap());
649value!(val: &'a [u8], Bytes, val.into());
650value!(val: f64, Double, val);
651value!(val: f32, Float, val);
652
653#[cfg(feature = "chrono")]
654value!(val: DateTime<Utc>, DateTime, val);
655#[cfg(feature = "chrono")]
656value!(val: chrono::NaiveTime, Time, val);
657#[cfg(feature = "chrono")]
658value!(val: chrono::NaiveDate, Date, val);
659#[cfg(feature = "bigdecimal")]
660value!(val: BigDecimal, Numeric, val);
661#[cfg(feature = "json")]
662value!(val: JsonValue, Json, val);
663#[cfg(feature = "uuid")]
664value!(val: Uuid, Uuid, val);
665
666impl<'a> TryFrom<Value<'a>> for i64 {
667 type Error = Error;
668
669 fn try_from(value: Value<'a>) -> Result<i64, Self::Error> {
670 value
671 .as_i64()
672 .ok_or_else(|| Error::builder(ErrorKind::conversion("Not an i64")).build())
673 }
674}
675
676impl<'a> TryFrom<Value<'a>> for i32 {
677 type Error = Error;
678
679 fn try_from(value: Value<'a>) -> Result<i32, Self::Error> {
680 value
681 .as_i32()
682 .ok_or_else(|| Error::builder(ErrorKind::conversion("Not an i32")).build())
683 }
684}
685
686#[cfg(feature = "bigdecimal")]
687impl<'a> TryFrom<Value<'a>> for BigDecimal {
688 type Error = Error;
689
690 fn try_from(value: Value<'a>) -> Result<BigDecimal, Self::Error> {
691 value
692 .into_numeric()
693 .ok_or_else(|| Error::builder(ErrorKind::conversion("Not a decimal")).build())
694 }
695}
696
697impl<'a> TryFrom<Value<'a>> for f64 {
698 type Error = Error;
699
700 fn try_from(value: Value<'a>) -> Result<f64, Self::Error> {
701 value
702 .as_f64()
703 .ok_or_else(|| Error::builder(ErrorKind::conversion("Not a f64")).build())
704 }
705}
706
707impl<'a> TryFrom<Value<'a>> for String {
708 type Error = Error;
709
710 fn try_from(value: Value<'a>) -> Result<String, Self::Error> {
711 value
712 .into_string()
713 .ok_or_else(|| Error::builder(ErrorKind::conversion("Not a string")).build())
714 }
715}
716
717impl<'a> TryFrom<Value<'a>> for bool {
718 type Error = Error;
719
720 fn try_from(value: Value<'a>) -> Result<bool, Self::Error> {
721 value
722 .as_bool()
723 .ok_or_else(|| Error::builder(ErrorKind::conversion("Not a bool")).build())
724 }
725}
726
727#[cfg(feature = "chrono")]
728impl<'a> TryFrom<Value<'a>> for DateTime<Utc> {
729 type Error = Error;
730
731 fn try_from(value: Value<'a>) -> Result<DateTime<Utc>, Self::Error> {
732 value
733 .as_datetime()
734 .ok_or_else(|| Error::builder(ErrorKind::conversion("Not a datetime")).build())
735 }
736}
737
738impl<'a> TryFrom<&Value<'a>> for Option<std::net::IpAddr> {
739 type Error = Error;
740
741 fn try_from(value: &Value<'a>) -> Result<Option<std::net::IpAddr>, Self::Error> {
742 match value {
743 val @ Value::Text(Some(_)) => {
744 let text = val.as_str().unwrap();
745
746 match std::net::IpAddr::from_str(text) {
747 Ok(ip) => Ok(Some(ip)),
748 Err(e) => Err(e.into()),
749 }
750 }
751 val @ Value::Bytes(Some(_)) => {
752 let text = val.as_str().unwrap();
753
754 match std::net::IpAddr::from_str(text) {
755 Ok(ip) => Ok(Some(ip)),
756 Err(e) => Err(e.into()),
757 }
758 }
759 v if v.is_null() => Ok(None),
760 v => {
761 let kind =
762 ErrorKind::conversion(format!("Couldn't convert value of type `{v:?}` to std::net::IpAddr."));
763
764 Err(Error::builder(kind).build())
765 }
766 }
767 }
768}
769
770#[cfg(feature = "uuid")]
771impl<'a> TryFrom<&Value<'a>> for Option<uuid::Uuid> {
772 type Error = Error;
773
774 fn try_from(value: &Value<'a>) -> Result<Option<uuid::Uuid>, Self::Error> {
775 match value {
776 Value::Uuid(uuid) => Ok(*uuid),
777 val @ Value::Text(Some(_)) => {
778 let text = val.as_str().unwrap();
779
780 match uuid::Uuid::from_str(text) {
781 Ok(ip) => Ok(Some(ip)),
782 Err(e) => Err(e.into()),
783 }
784 }
785 val @ Value::Bytes(Some(_)) => {
786 let text = val.as_str().unwrap();
787
788 match uuid::Uuid::from_str(text) {
789 Ok(ip) => Ok(Some(ip)),
790 Err(e) => Err(e.into()),
791 }
792 }
793 v if v.is_null() => Ok(None),
794 v => {
795 let kind = ErrorKind::conversion(format!("Couldn't convert value of type `{v:?}` to uuid::Uuid."));
796
797 Err(Error::builder(kind).build())
798 }
799 }
800 }
801}
802
803#[derive(Debug, Clone, Default, PartialEq)]
806pub struct Values<'a> {
807 pub(crate) rows: Vec<Row<'a>>,
808}
809
810impl<'a> Values<'a> {
811 pub fn empty() -> Self {
813 Self { rows: Vec::new() }
814 }
815
816 pub fn new(rows: Vec<Row<'a>>) -> Self {
818 Self { rows }
819 }
820
821 pub fn with_capacity(capacity: usize) -> Self {
823 Self {
824 rows: Vec::with_capacity(capacity),
825 }
826 }
827
828 pub fn push<T>(&mut self, row: T)
830 where
831 T: Into<Row<'a>>,
832 {
833 self.rows.push(row.into());
834 }
835
836 pub fn len(&self) -> usize {
838 self.rows.len()
839 }
840
841 pub fn is_empty(&self) -> bool {
843 self.len() == 0
844 }
845
846 pub fn row_len(&self) -> usize {
847 match self.rows.split_first() {
848 Some((row, _)) => row.len(),
849 None => 0,
850 }
851 }
852
853 pub fn flatten_row(self) -> Option<Row<'a>> {
854 let mut result = Row::with_capacity(self.len());
855
856 for mut row in self.rows.into_iter() {
857 match row.pop() {
858 Some(value) => result.push(value),
859 None => return None,
860 }
861 }
862
863 Some(result)
864 }
865}
866
867impl<'a, I, R> From<I> for Values<'a>
868where
869 I: Iterator<Item = R>,
870 R: Into<Row<'a>>,
871{
872 fn from(rows: I) -> Self {
873 Self {
874 rows: rows.map(|r| r.into()).collect(),
875 }
876 }
877}
878
879impl<'a> IntoIterator for Values<'a> {
880 type Item = Row<'a>;
881 type IntoIter = std::vec::IntoIter<Self::Item>;
882
883 fn into_iter(self) -> Self::IntoIter {
884 self.rows.into_iter()
885 }
886}
887
888#[cfg(test)]
889mod tests {
890 use super::*;
891 #[cfg(feature = "chrono")]
892 use std::str::FromStr;
893
894 #[test]
895 fn a_parameterized_value_of_ints32_can_be_converted_into_a_vec() {
896 let pv = Value::array(vec![1]);
897 let values: Vec<i32> = pv.into_vec().expect("convert into Vec<i32>");
898 assert_eq!(values, vec![1]);
899 }
900
901 #[test]
902 fn a_parameterized_value_of_ints64_can_be_converted_into_a_vec() {
903 let pv = Value::array(vec![1_i64]);
904 let values: Vec<i64> = pv.into_vec().expect("convert into Vec<i64>");
905 assert_eq!(values, vec![1]);
906 }
907
908 #[test]
909 fn a_parameterized_value_of_reals_can_be_converted_into_a_vec() {
910 let pv = Value::array(vec![1.0]);
911 let values: Vec<f64> = pv.into_vec().expect("convert into Vec<f64>");
912 assert_eq!(values, vec![1.0]);
913 }
914
915 #[test]
916 fn a_parameterized_value_of_texts_can_be_converted_into_a_vec() {
917 let pv = Value::array(vec!["test"]);
918 let values: Vec<String> = pv.into_vec().expect("convert into Vec<String>");
919 assert_eq!(values, vec!["test"]);
920 }
921
922 #[test]
923 fn a_parameterized_value_of_booleans_can_be_converted_into_a_vec() {
924 let pv = Value::array(vec![true]);
925 let values: Vec<bool> = pv.into_vec().expect("convert into Vec<bool>");
926 assert_eq!(values, vec![true]);
927 }
928
929 #[test]
930 #[cfg(feature = "chrono")]
931 fn a_parameterized_value_of_datetimes_can_be_converted_into_a_vec() {
932 let datetime = DateTime::from_str("2019-07-27T05:30:30Z").expect("parsing date/time");
933 let pv = Value::array(vec![datetime]);
934 let values: Vec<DateTime<Utc>> = pv.into_vec().expect("convert into Vec<DateTime>");
935 assert_eq!(values, vec![datetime]);
936 }
937
938 #[test]
939 fn a_parameterized_value_of_an_array_cant_be_converted_into_a_vec_of_the_wrong_type() {
940 let pv = Value::array(vec![1]);
941 let rslt: Option<Vec<f64>> = pv.into_vec();
942 assert!(rslt.is_none());
943 }
944
945 #[test]
946 #[cfg(feature = "chrono")]
947 fn display_format_for_datetime() {
948 let dt: DateTime<Utc> = DateTime::from_str("2019-07-27T05:30:30Z").expect("failed while parsing date");
949 let pv = Value::datetime(dt);
950
951 assert_eq!(format!("{pv}"), "\"2019-07-27 05:30:30 UTC\"");
952 }
953
954 #[test]
955 #[cfg(feature = "chrono")]
956 fn display_format_for_date() {
957 let date = NaiveDate::from_ymd_opt(2022, 8, 11).unwrap();
958 let pv = Value::date(date);
959
960 assert_eq!(format!("{pv}"), "\"2022-08-11\"");
961 }
962
963 #[test]
964 #[cfg(feature = "chrono")]
965 fn display_format_for_time() {
966 let time = NaiveTime::from_hms_opt(16, 17, 00).unwrap();
967 let pv = Value::time(time);
968
969 assert_eq!(format!("{pv}"), "\"16:17:00\"");
970 }
971
972 #[test]
973 #[cfg(feature = "uuid")]
974 fn display_format_for_uuid() {
975 let id = Uuid::from_str("67e5504410b1426f9247bb680e5fe0c8").unwrap();
976 let pv = Value::uuid(id);
977
978 assert_eq!(format!("{pv}"), "\"67e55044-10b1-426f-9247-bb680e5fe0c8\"");
979 }
980}