sea_query/
value.rs

1//! Container for all SQL value types.
2
3use std::borrow::Cow;
4
5#[cfg(feature = "with-json")]
6use serde_json::Value as Json;
7#[cfg(feature = "with-json")]
8use std::str::from_utf8;
9
10#[cfg(feature = "with-chrono")]
11use chrono::{DateTime, FixedOffset, Local, NaiveDate, NaiveDateTime, NaiveTime, Utc};
12
13#[cfg(feature = "with-time")]
14use time::{OffsetDateTime, PrimitiveDateTime};
15
16#[cfg(feature = "with-rust_decimal")]
17use rust_decimal::Decimal;
18
19#[cfg(feature = "with-bigdecimal")]
20use bigdecimal::BigDecimal;
21
22#[cfg(feature = "with-uuid")]
23use uuid::Uuid;
24
25#[cfg(feature = "with-ipnetwork")]
26use ipnetwork::IpNetwork;
27
28#[cfg(feature = "with-ipnetwork")]
29use std::net::IpAddr;
30
31#[cfg(feature = "with-mac_address")]
32use mac_address::MacAddress;
33
34use crate::{ColumnType, CommonSqlQueryBuilder, QueryBuilder, StringLen};
35
36/// [`Value`] types variant for Postgres array
37#[derive(Clone, Debug, Eq, PartialEq, Hash)]
38pub enum ArrayType {
39    Bool,
40    TinyInt,
41    SmallInt,
42    Int,
43    BigInt,
44    TinyUnsigned,
45    SmallUnsigned,
46    Unsigned,
47    BigUnsigned,
48    Float,
49    Double,
50    String,
51    Char,
52    Bytes,
53
54    #[cfg(feature = "with-json")]
55    #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
56    Json,
57
58    #[cfg(feature = "with-chrono")]
59    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
60    ChronoDate,
61
62    #[cfg(feature = "with-chrono")]
63    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
64    ChronoTime,
65
66    #[cfg(feature = "with-chrono")]
67    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
68    ChronoDateTime,
69
70    #[cfg(feature = "with-chrono")]
71    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
72    ChronoDateTimeUtc,
73
74    #[cfg(feature = "with-chrono")]
75    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
76    ChronoDateTimeLocal,
77
78    #[cfg(feature = "with-chrono")]
79    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
80    ChronoDateTimeWithTimeZone,
81
82    #[cfg(feature = "with-time")]
83    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
84    TimeDate,
85
86    #[cfg(feature = "with-time")]
87    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
88    TimeTime,
89
90    #[cfg(feature = "with-time")]
91    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
92    TimeDateTime,
93
94    #[cfg(feature = "with-time")]
95    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
96    TimeDateTimeWithTimeZone,
97
98    #[cfg(feature = "with-uuid")]
99    #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
100    Uuid,
101
102    #[cfg(feature = "with-rust_decimal")]
103    #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
104    Decimal,
105
106    #[cfg(feature = "with-bigdecimal")]
107    #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
108    BigDecimal,
109
110    #[cfg(feature = "with-ipnetwork")]
111    #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
112    IpNetwork,
113
114    #[cfg(feature = "with-mac_address")]
115    #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
116    MacAddress,
117}
118
119/// Value variants
120///
121/// We want the inner Value to be exactly 1 pointer sized, so anything larger should be boxed.
122///
123/// If the `hashable-value` feature is enabled, NaN == NaN, which contradicts Rust's built-in
124/// implementation of NaN != NaN.
125#[derive(Clone, Debug)]
126#[cfg_attr(not(feature = "hashable-value"), derive(PartialEq))]
127pub enum Value {
128    Bool(Option<bool>),
129    TinyInt(Option<i8>),
130    SmallInt(Option<i16>),
131    Int(Option<i32>),
132    BigInt(Option<i64>),
133    TinyUnsigned(Option<u8>),
134    SmallUnsigned(Option<u16>),
135    Unsigned(Option<u32>),
136    BigUnsigned(Option<u64>),
137    Float(Option<f32>),
138    Double(Option<f64>),
139    String(Option<Box<String>>),
140    Char(Option<char>),
141
142    #[allow(clippy::box_collection)]
143    Bytes(Option<Box<Vec<u8>>>),
144
145    #[cfg(feature = "with-json")]
146    #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
147    Json(Option<Box<Json>>),
148
149    #[cfg(feature = "with-chrono")]
150    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
151    ChronoDate(Option<Box<NaiveDate>>),
152
153    #[cfg(feature = "with-chrono")]
154    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
155    ChronoTime(Option<Box<NaiveTime>>),
156
157    #[cfg(feature = "with-chrono")]
158    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
159    ChronoDateTime(Option<Box<NaiveDateTime>>),
160
161    #[cfg(feature = "with-chrono")]
162    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
163    ChronoDateTimeUtc(Option<Box<DateTime<Utc>>>),
164
165    #[cfg(feature = "with-chrono")]
166    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
167    ChronoDateTimeLocal(Option<Box<DateTime<Local>>>),
168
169    #[cfg(feature = "with-chrono")]
170    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
171    ChronoDateTimeWithTimeZone(Option<Box<DateTime<FixedOffset>>>),
172
173    #[cfg(feature = "with-time")]
174    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
175    TimeDate(Option<Box<time::Date>>),
176
177    #[cfg(feature = "with-time")]
178    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
179    TimeTime(Option<Box<time::Time>>),
180
181    #[cfg(feature = "with-time")]
182    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
183    TimeDateTime(Option<Box<PrimitiveDateTime>>),
184
185    #[cfg(feature = "with-time")]
186    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
187    TimeDateTimeWithTimeZone(Option<Box<OffsetDateTime>>),
188
189    #[cfg(feature = "with-uuid")]
190    #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
191    Uuid(Option<Box<Uuid>>),
192
193    #[cfg(feature = "with-rust_decimal")]
194    #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
195    Decimal(Option<Box<Decimal>>),
196
197    #[cfg(feature = "with-bigdecimal")]
198    #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
199    BigDecimal(Option<Box<BigDecimal>>),
200
201    #[cfg(feature = "postgres-array")]
202    #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
203    Array(ArrayType, Option<Box<Vec<Value>>>),
204
205    #[cfg(feature = "postgres-vector")]
206    #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
207    Vector(Option<Box<pgvector::Vector>>),
208
209    #[cfg(feature = "with-ipnetwork")]
210    #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
211    IpNetwork(Option<Box<IpNetwork>>),
212
213    #[cfg(feature = "with-mac_address")]
214    #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
215    MacAddress(Option<Box<MacAddress>>),
216}
217
218impl std::fmt::Display for Value {
219    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
220        write!(f, "{}", CommonSqlQueryBuilder.value_to_string(self))
221    }
222}
223
224pub trait ValueType: Sized {
225    fn try_from(v: Value) -> Result<Self, ValueTypeErr>;
226
227    fn unwrap(v: Value) -> Self {
228        Self::try_from(v).unwrap()
229    }
230
231    fn expect(v: Value, msg: &str) -> Self {
232        Self::try_from(v).expect(msg)
233    }
234
235    fn type_name() -> String;
236
237    fn array_type() -> ArrayType;
238
239    fn column_type() -> ColumnType;
240
241    fn enum_type_name() -> Option<&'static str> {
242        None
243    }
244}
245
246#[derive(Debug)]
247pub struct ValueTypeErr;
248
249impl std::error::Error for ValueTypeErr {}
250
251impl std::fmt::Display for ValueTypeErr {
252    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
253        write!(f, "Value type mismatch")
254    }
255}
256
257#[derive(Clone, Debug, PartialEq)]
258pub struct Values(pub Vec<Value>);
259
260#[derive(Clone, Debug, PartialEq)]
261#[cfg_attr(feature = "hashable-value", derive(Hash, Eq))]
262pub enum ValueTuple {
263    One(Value),
264    Two(Value, Value),
265    Three(Value, Value, Value),
266    Many(Vec<Value>),
267}
268
269pub trait IntoValueTuple {
270    fn into_value_tuple(self) -> ValueTuple;
271}
272
273pub trait FromValueTuple: Sized {
274    fn from_value_tuple<I>(i: I) -> Self
275    where
276        I: IntoValueTuple;
277}
278
279pub trait Nullable {
280    fn null() -> Value;
281}
282
283impl Value {
284    pub fn unwrap<T>(self) -> T
285    where
286        T: ValueType,
287    {
288        T::unwrap(self)
289    }
290
291    pub fn expect<T>(self, msg: &str) -> T
292    where
293        T: ValueType,
294    {
295        T::expect(self, msg)
296    }
297
298    /// Get the null variant of self
299    ///
300    /// ```
301    /// use sea_query::Value;
302    ///
303    /// let v = Value::Int(Some(2));
304    /// let n = v.as_null();
305    ///
306    /// assert_eq!(n, Value::Int(None));
307    ///
308    /// // one liner:
309    /// assert_eq!(Into::<Value>::into(2.2).as_null(), Value::Double(None));
310    /// ```
311    pub fn as_null(&self) -> Self {
312        match self {
313            Self::Bool(_) => Self::Bool(None),
314            Self::TinyInt(_) => Self::TinyInt(None),
315            Self::SmallInt(_) => Self::SmallInt(None),
316            Self::Int(_) => Self::Int(None),
317            Self::BigInt(_) => Self::BigInt(None),
318            Self::TinyUnsigned(_) => Self::TinyUnsigned(None),
319            Self::SmallUnsigned(_) => Self::SmallUnsigned(None),
320            Self::Unsigned(_) => Self::Unsigned(None),
321            Self::BigUnsigned(_) => Self::BigUnsigned(None),
322            Self::Float(_) => Self::Float(None),
323            Self::Double(_) => Self::Double(None),
324            Self::String(_) => Self::String(None),
325            Self::Char(_) => Self::Char(None),
326            Self::Bytes(_) => Self::Bytes(None),
327
328            #[cfg(feature = "with-json")]
329            #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
330            Self::Json(_) => Self::Json(None),
331
332            #[cfg(feature = "with-chrono")]
333            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
334            Self::ChronoDate(_) => Self::ChronoDate(None),
335
336            #[cfg(feature = "with-chrono")]
337            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
338            Self::ChronoTime(_) => Self::ChronoTime(None),
339
340            #[cfg(feature = "with-chrono")]
341            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
342            Self::ChronoDateTime(_) => Self::ChronoDateTime(None),
343
344            #[cfg(feature = "with-chrono")]
345            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
346            Self::ChronoDateTimeUtc(_) => Self::ChronoDateTimeUtc(None),
347
348            #[cfg(feature = "with-chrono")]
349            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
350            Self::ChronoDateTimeLocal(_) => Self::ChronoDateTimeLocal(None),
351
352            #[cfg(feature = "with-chrono")]
353            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
354            Self::ChronoDateTimeWithTimeZone(_) => Self::ChronoDateTimeWithTimeZone(None),
355
356            #[cfg(feature = "with-time")]
357            #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
358            Self::TimeDate(_) => Self::TimeDate(None),
359
360            #[cfg(feature = "with-time")]
361            #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
362            Self::TimeTime(_) => Self::TimeTime(None),
363
364            #[cfg(feature = "with-time")]
365            #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
366            Self::TimeDateTime(_) => Self::TimeDateTime(None),
367
368            #[cfg(feature = "with-time")]
369            #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
370            Self::TimeDateTimeWithTimeZone(_) => Self::TimeDateTimeWithTimeZone(None),
371
372            #[cfg(feature = "with-uuid")]
373            #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
374            Self::Uuid(_) => Self::Uuid(None),
375
376            #[cfg(feature = "with-rust_decimal")]
377            #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
378            Self::Decimal(_) => Self::Decimal(None),
379
380            #[cfg(feature = "with-bigdecimal")]
381            #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
382            Self::BigDecimal(_) => Self::BigDecimal(None),
383
384            #[cfg(feature = "postgres-array")]
385            #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
386            Self::Array(ty, _) => Self::Array(ty.clone(), None),
387
388            #[cfg(feature = "postgres-vector")]
389            #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
390            Self::Vector(_) => Self::Vector(None),
391
392            #[cfg(feature = "with-ipnetwork")]
393            #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
394            Self::IpNetwork(_) => Self::IpNetwork(None),
395
396            #[cfg(feature = "with-mac_address")]
397            #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
398            Self::MacAddress(_) => Self::MacAddress(None),
399        }
400    }
401}
402
403macro_rules! type_to_value {
404    ( $type: ty, $name: ident, $col_type: expr ) => {
405        impl From<$type> for Value {
406            fn from(x: $type) -> Value {
407                Value::$name(Some(x))
408            }
409        }
410
411        impl Nullable for $type {
412            fn null() -> Value {
413                Value::$name(None)
414            }
415        }
416
417        impl ValueType for $type {
418            fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
419                match v {
420                    Value::$name(Some(x)) => Ok(x),
421                    _ => Err(ValueTypeErr),
422                }
423            }
424
425            fn type_name() -> String {
426                stringify!($type).to_owned()
427            }
428
429            fn array_type() -> ArrayType {
430                ArrayType::$name
431            }
432
433            fn column_type() -> ColumnType {
434                use ColumnType::*;
435                $col_type
436            }
437        }
438    };
439}
440
441macro_rules! type_to_box_value {
442    ( $type: ty, $name: ident, $col_type: expr ) => {
443        impl From<$type> for Value {
444            fn from(x: $type) -> Value {
445                Value::$name(Some(Box::new(x)))
446            }
447        }
448
449        impl Nullable for $type {
450            fn null() -> Value {
451                Value::$name(None)
452            }
453        }
454
455        impl ValueType for $type {
456            fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
457                match v {
458                    Value::$name(Some(x)) => Ok(*x),
459                    _ => Err(ValueTypeErr),
460                }
461            }
462
463            fn type_name() -> String {
464                stringify!($type).to_owned()
465            }
466
467            fn array_type() -> ArrayType {
468                ArrayType::$name
469            }
470
471            fn column_type() -> ColumnType {
472                use ColumnType::*;
473                $col_type
474            }
475        }
476    };
477}
478
479type_to_value!(bool, Bool, Boolean);
480type_to_value!(i8, TinyInt, TinyInteger);
481type_to_value!(i16, SmallInt, SmallInteger);
482type_to_value!(i32, Int, Integer);
483type_to_value!(i64, BigInt, BigInteger);
484type_to_value!(u8, TinyUnsigned, TinyUnsigned);
485type_to_value!(u16, SmallUnsigned, SmallUnsigned);
486type_to_value!(u32, Unsigned, Unsigned);
487type_to_value!(u64, BigUnsigned, BigUnsigned);
488type_to_value!(f32, Float, Float);
489type_to_value!(f64, Double, Double);
490type_to_value!(char, Char, Char(None));
491
492impl From<&[u8]> for Value {
493    fn from(x: &[u8]) -> Value {
494        Value::Bytes(Some(Box::<Vec<u8>>::new(x.into())))
495    }
496}
497
498impl From<&str> for Value {
499    fn from(x: &str) -> Value {
500        let string: String = x.into();
501        Value::String(Some(Box::new(string)))
502    }
503}
504
505impl From<&String> for Value {
506    fn from(x: &String) -> Value {
507        let string: String = x.into();
508        Value::String(Some(Box::new(string)))
509    }
510}
511
512impl Nullable for &str {
513    fn null() -> Value {
514        Value::String(None)
515    }
516}
517
518impl<T> From<Option<T>> for Value
519where
520    T: Into<Value> + Nullable,
521{
522    fn from(x: Option<T>) -> Value {
523        match x {
524            Some(v) => v.into(),
525            None => T::null(),
526        }
527    }
528}
529
530impl<T> ValueType for Option<T>
531where
532    T: ValueType + Nullable,
533{
534    fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
535        if v == T::null() {
536            Ok(None)
537        } else {
538            Ok(Some(T::try_from(v)?))
539        }
540    }
541
542    fn type_name() -> String {
543        format!("Option<{}>", T::type_name())
544    }
545
546    fn array_type() -> ArrayType {
547        T::array_type()
548    }
549
550    fn column_type() -> ColumnType {
551        T::column_type()
552    }
553}
554
555impl From<Cow<'_, str>> for Value {
556    fn from(x: Cow<'_, str>) -> Value {
557        x.into_owned().into()
558    }
559}
560
561impl ValueType for Cow<'_, str> {
562    fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
563        match v {
564            Value::String(Some(x)) => Ok((*x).into()),
565            _ => Err(ValueTypeErr),
566        }
567    }
568
569    fn type_name() -> String {
570        "Cow<str>".into()
571    }
572
573    fn array_type() -> ArrayType {
574        ArrayType::String
575    }
576
577    fn column_type() -> ColumnType {
578        ColumnType::String(StringLen::None)
579    }
580}
581
582type_to_box_value!(Vec<u8>, Bytes, VarBinary(StringLen::None));
583type_to_box_value!(String, String, String(StringLen::None));
584
585#[cfg(feature = "with-json")]
586#[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
587mod with_json {
588    use super::*;
589
590    type_to_box_value!(Json, Json, Json);
591}
592
593#[cfg(feature = "with-chrono")]
594#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
595mod with_chrono {
596    use super::*;
597    use chrono::{Local, Offset, Utc};
598
599    type_to_box_value!(NaiveDate, ChronoDate, Date);
600    type_to_box_value!(NaiveTime, ChronoTime, Time);
601    type_to_box_value!(NaiveDateTime, ChronoDateTime, DateTime);
602
603    impl From<DateTime<Utc>> for Value {
604        fn from(v: DateTime<Utc>) -> Value {
605            Value::ChronoDateTimeUtc(Some(Box::new(v)))
606        }
607    }
608
609    impl From<DateTime<Local>> for Value {
610        fn from(v: DateTime<Local>) -> Value {
611            Value::ChronoDateTimeLocal(Some(Box::new(v)))
612        }
613    }
614
615    impl From<DateTime<FixedOffset>> for Value {
616        fn from(x: DateTime<FixedOffset>) -> Value {
617            let v =
618                DateTime::<FixedOffset>::from_naive_utc_and_offset(x.naive_utc(), x.offset().fix());
619            Value::ChronoDateTimeWithTimeZone(Some(Box::new(v)))
620        }
621    }
622
623    impl Nullable for DateTime<Utc> {
624        fn null() -> Value {
625            Value::ChronoDateTimeUtc(None)
626        }
627    }
628
629    impl ValueType for DateTime<Utc> {
630        fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
631            match v {
632                Value::ChronoDateTimeUtc(Some(x)) => Ok(*x),
633                _ => Err(ValueTypeErr),
634            }
635        }
636
637        fn type_name() -> String {
638            stringify!(DateTime<Utc>).to_owned()
639        }
640
641        fn array_type() -> ArrayType {
642            ArrayType::ChronoDateTimeUtc
643        }
644
645        fn column_type() -> ColumnType {
646            ColumnType::TimestampWithTimeZone
647        }
648    }
649
650    impl Nullable for DateTime<Local> {
651        fn null() -> Value {
652            Value::ChronoDateTimeLocal(None)
653        }
654    }
655
656    impl ValueType for DateTime<Local> {
657        fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
658            match v {
659                Value::ChronoDateTimeLocal(Some(x)) => Ok(*x),
660                _ => Err(ValueTypeErr),
661            }
662        }
663
664        fn type_name() -> String {
665            stringify!(DateTime<Local>).to_owned()
666        }
667
668        fn array_type() -> ArrayType {
669            ArrayType::ChronoDateTimeLocal
670        }
671
672        fn column_type() -> ColumnType {
673            ColumnType::TimestampWithTimeZone
674        }
675    }
676
677    impl Nullable for DateTime<FixedOffset> {
678        fn null() -> Value {
679            Value::ChronoDateTimeWithTimeZone(None)
680        }
681    }
682
683    impl ValueType for DateTime<FixedOffset> {
684        fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
685            match v {
686                Value::ChronoDateTimeWithTimeZone(Some(x)) => Ok(*x),
687                _ => Err(ValueTypeErr),
688            }
689        }
690
691        fn type_name() -> String {
692            stringify!(DateTime<FixedOffset>).to_owned()
693        }
694
695        fn array_type() -> ArrayType {
696            ArrayType::ChronoDateTimeWithTimeZone
697        }
698
699        fn column_type() -> ColumnType {
700            ColumnType::TimestampWithTimeZone
701        }
702    }
703}
704
705#[cfg(feature = "with-time")]
706#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
707pub mod time_format {
708    use time::format_description::FormatItem;
709    use time::macros::format_description;
710
711    pub static FORMAT_DATE: &[FormatItem<'static>] = format_description!("[year]-[month]-[day]");
712    pub static FORMAT_TIME: &[FormatItem<'static>] =
713        format_description!("[hour]:[minute]:[second].[subsecond digits:6]");
714    pub static FORMAT_DATETIME: &[FormatItem<'static>] =
715        format_description!("[year]-[month]-[day] [hour]:[minute]:[second].[subsecond digits:6]");
716    pub static FORMAT_DATETIME_TZ: &[FormatItem<'static>] = format_description!(
717        "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond digits:6] [offset_hour sign:mandatory]:[offset_minute]"
718    );
719}
720
721#[cfg(feature = "with-time")]
722#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
723mod with_time {
724    use super::*;
725
726    type_to_box_value!(time::Date, TimeDate, Date);
727    type_to_box_value!(time::Time, TimeTime, Time);
728    type_to_box_value!(PrimitiveDateTime, TimeDateTime, DateTime);
729
730    impl From<OffsetDateTime> for Value {
731        fn from(v: OffsetDateTime) -> Value {
732            Value::TimeDateTimeWithTimeZone(Some(Box::new(v)))
733        }
734    }
735
736    impl Nullable for OffsetDateTime {
737        fn null() -> Value {
738            Value::TimeDateTimeWithTimeZone(None)
739        }
740    }
741
742    impl ValueType for OffsetDateTime {
743        fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
744            match v {
745                Value::TimeDateTimeWithTimeZone(Some(x)) => Ok(*x),
746                _ => Err(ValueTypeErr),
747            }
748        }
749
750        fn type_name() -> String {
751            stringify!(OffsetDateTime).to_owned()
752        }
753
754        fn array_type() -> ArrayType {
755            ArrayType::TimeDateTimeWithTimeZone
756        }
757
758        fn column_type() -> ColumnType {
759            ColumnType::TimestampWithTimeZone
760        }
761    }
762}
763
764#[cfg(feature = "with-rust_decimal")]
765#[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
766mod with_rust_decimal {
767    use super::*;
768
769    type_to_box_value!(Decimal, Decimal, Decimal(None));
770}
771
772#[cfg(feature = "with-bigdecimal")]
773#[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
774mod with_bigdecimal {
775    use super::*;
776
777    type_to_box_value!(BigDecimal, BigDecimal, Decimal(None));
778}
779
780#[cfg(feature = "with-uuid")]
781#[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
782mod with_uuid {
783    use super::*;
784
785    type_to_box_value!(Uuid, Uuid, Uuid);
786
787    macro_rules! fmt_uuid_to_box_value {
788        ( $type: ty, $conversion_fn: ident ) => {
789            impl From<$type> for Value {
790                fn from(x: $type) -> Value {
791                    Value::Uuid(Some(Box::new(x.into_uuid())))
792                }
793            }
794
795            impl Nullable for $type {
796                fn null() -> Value {
797                    Value::Uuid(None)
798                }
799            }
800
801            impl ValueType for $type {
802                fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
803                    match v {
804                        Value::Uuid(Some(x)) => Ok(x.$conversion_fn()),
805                        _ => Err(ValueTypeErr),
806                    }
807                }
808
809                fn type_name() -> String {
810                    stringify!($type).to_owned()
811                }
812
813                fn array_type() -> ArrayType {
814                    ArrayType::Uuid
815                }
816
817                fn column_type() -> ColumnType {
818                    ColumnType::Uuid
819                }
820            }
821        };
822    }
823
824    fmt_uuid_to_box_value!(uuid::fmt::Braced, braced);
825    fmt_uuid_to_box_value!(uuid::fmt::Hyphenated, hyphenated);
826    fmt_uuid_to_box_value!(uuid::fmt::Simple, simple);
827    fmt_uuid_to_box_value!(uuid::fmt::Urn, urn);
828}
829
830#[cfg(feature = "with-ipnetwork")]
831#[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
832mod with_ipnetwork {
833    use super::*;
834
835    type_to_box_value!(IpNetwork, IpNetwork, Inet);
836}
837
838#[cfg(feature = "with-mac_address")]
839#[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
840mod with_mac_address {
841    use super::*;
842
843    type_to_box_value!(MacAddress, MacAddress, MacAddr);
844}
845
846#[cfg(feature = "postgres-array")]
847#[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
848pub mod with_array {
849    use super::*;
850    use crate::RcOrArc;
851
852    // We only implement conversion from Vec<T> to Array when T is not u8.
853    // This is because for u8's case, there is already conversion to Byte defined above.
854    // TODO When negative trait becomes a stable feature, following code can be much shorter.
855    pub trait NotU8 {}
856
857    impl NotU8 for bool {}
858    impl NotU8 for i8 {}
859    impl NotU8 for i16 {}
860    impl NotU8 for i32 {}
861    impl NotU8 for i64 {}
862    impl NotU8 for u16 {}
863    impl NotU8 for u32 {}
864    impl NotU8 for u64 {}
865    impl NotU8 for f32 {}
866    impl NotU8 for f64 {}
867    impl NotU8 for char {}
868    impl NotU8 for String {}
869    impl NotU8 for Vec<u8> {}
870
871    // TODO impl<T: NotU8> NotU8 for Option<T> {}
872
873    #[cfg(feature = "with-json")]
874    impl NotU8 for Json {}
875
876    #[cfg(feature = "with-chrono")]
877    impl NotU8 for NaiveDate {}
878
879    #[cfg(feature = "with-chrono")]
880    impl NotU8 for NaiveTime {}
881
882    #[cfg(feature = "with-chrono")]
883    impl NotU8 for NaiveDateTime {}
884
885    #[cfg(feature = "with-chrono")]
886    impl<Tz> NotU8 for DateTime<Tz> where Tz: chrono::TimeZone {}
887
888    #[cfg(feature = "with-time")]
889    impl NotU8 for time::Date {}
890
891    #[cfg(feature = "with-time")]
892    impl NotU8 for time::Time {}
893
894    #[cfg(feature = "with-time")]
895    impl NotU8 for PrimitiveDateTime {}
896
897    #[cfg(feature = "with-time")]
898    impl NotU8 for OffsetDateTime {}
899
900    #[cfg(feature = "with-rust_decimal")]
901    impl NotU8 for Decimal {}
902
903    #[cfg(feature = "with-bigdecimal")]
904    impl NotU8 for BigDecimal {}
905
906    #[cfg(feature = "with-uuid")]
907    impl NotU8 for Uuid {}
908
909    #[cfg(feature = "with-uuid")]
910    impl NotU8 for uuid::fmt::Braced {}
911
912    #[cfg(feature = "with-uuid")]
913    impl NotU8 for uuid::fmt::Hyphenated {}
914
915    #[cfg(feature = "with-uuid")]
916    impl NotU8 for uuid::fmt::Simple {}
917
918    #[cfg(feature = "with-uuid")]
919    impl NotU8 for uuid::fmt::Urn {}
920
921    #[cfg(feature = "with-ipnetwork")]
922    impl NotU8 for IpNetwork {}
923
924    #[cfg(feature = "with-mac_address")]
925    impl NotU8 for MacAddress {}
926
927    impl<T> From<Vec<T>> for Value
928    where
929        T: Into<Value> + NotU8 + ValueType,
930    {
931        fn from(x: Vec<T>) -> Value {
932            Value::Array(
933                T::array_type(),
934                Some(Box::new(x.into_iter().map(|e| e.into()).collect())),
935            )
936        }
937    }
938
939    impl<T> Nullable for Vec<T>
940    where
941        T: Into<Value> + NotU8 + ValueType,
942    {
943        fn null() -> Value {
944            Value::Array(T::array_type(), None)
945        }
946    }
947
948    impl<T> ValueType for Vec<T>
949    where
950        T: NotU8 + ValueType,
951    {
952        fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
953            match v {
954                Value::Array(ty, Some(v)) if T::array_type() == ty => {
955                    Ok(v.into_iter().map(|e| e.unwrap()).collect())
956                }
957                _ => Err(ValueTypeErr),
958            }
959        }
960
961        fn type_name() -> String {
962            stringify!(Vec<T>).to_owned()
963        }
964
965        fn array_type() -> ArrayType {
966            T::array_type()
967        }
968
969        fn column_type() -> ColumnType {
970            use ColumnType::*;
971            Array(RcOrArc::new(T::column_type()))
972        }
973    }
974}
975
976#[cfg(feature = "postgres-vector")]
977#[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
978pub mod with_vector {
979    use super::*;
980
981    impl From<pgvector::Vector> for Value {
982        fn from(x: pgvector::Vector) -> Value {
983            Value::Vector(Some(Box::new(x)))
984        }
985    }
986
987    impl Nullable for pgvector::Vector {
988        fn null() -> Value {
989            Value::Vector(None)
990        }
991    }
992
993    impl ValueType for pgvector::Vector {
994        fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
995            match v {
996                Value::Vector(Some(x)) => Ok(*x),
997                _ => Err(ValueTypeErr),
998            }
999        }
1000
1001        fn type_name() -> String {
1002            stringify!(Vector).to_owned()
1003        }
1004
1005        fn array_type() -> ArrayType {
1006            unimplemented!("Vector does not have array type")
1007        }
1008
1009        fn column_type() -> ColumnType {
1010            ColumnType::Vector(None)
1011        }
1012    }
1013}
1014
1015#[allow(unused_macros)]
1016macro_rules! box_to_opt_ref {
1017    ( $v: expr ) => {
1018        match $v {
1019            Some(v) => Some(v.as_ref()),
1020            None => None,
1021        }
1022    };
1023}
1024
1025#[cfg(feature = "with-json")]
1026impl Value {
1027    pub fn is_json(&self) -> bool {
1028        matches!(self, Self::Json(_))
1029    }
1030
1031    pub fn as_ref_json(&self) -> Option<&Json> {
1032        match self {
1033            Self::Json(v) => box_to_opt_ref!(v),
1034            _ => panic!("not Value::Json"),
1035        }
1036    }
1037}
1038
1039#[cfg(feature = "with-chrono")]
1040impl Value {
1041    pub fn is_chrono_date(&self) -> bool {
1042        matches!(self, Self::ChronoDate(_))
1043    }
1044
1045    pub fn as_ref_chrono_date(&self) -> Option<&NaiveDate> {
1046        match self {
1047            Self::ChronoDate(v) => box_to_opt_ref!(v),
1048            _ => panic!("not Value::ChronoDate"),
1049        }
1050    }
1051}
1052
1053#[cfg(feature = "with-time")]
1054impl Value {
1055    pub fn is_time_date(&self) -> bool {
1056        matches!(self, Self::TimeDate(_))
1057    }
1058
1059    pub fn as_ref_time_date(&self) -> Option<&time::Date> {
1060        match self {
1061            Self::TimeDate(v) => box_to_opt_ref!(v),
1062            _ => panic!("not Value::TimeDate"),
1063        }
1064    }
1065}
1066
1067#[cfg(feature = "with-chrono")]
1068impl Value {
1069    pub fn is_chrono_time(&self) -> bool {
1070        matches!(self, Self::ChronoTime(_))
1071    }
1072
1073    pub fn as_ref_chrono_time(&self) -> Option<&NaiveTime> {
1074        match self {
1075            Self::ChronoTime(v) => box_to_opt_ref!(v),
1076            _ => panic!("not Value::ChronoTime"),
1077        }
1078    }
1079}
1080
1081#[cfg(feature = "with-time")]
1082impl Value {
1083    pub fn is_time_time(&self) -> bool {
1084        matches!(self, Self::TimeTime(_))
1085    }
1086
1087    pub fn as_ref_time_time(&self) -> Option<&time::Time> {
1088        match self {
1089            Self::TimeTime(v) => box_to_opt_ref!(v),
1090            _ => panic!("not Value::TimeTime"),
1091        }
1092    }
1093}
1094
1095#[cfg(feature = "with-chrono")]
1096impl Value {
1097    pub fn is_chrono_date_time(&self) -> bool {
1098        matches!(self, Self::ChronoDateTime(_))
1099    }
1100
1101    pub fn as_ref_chrono_date_time(&self) -> Option<&NaiveDateTime> {
1102        match self {
1103            Self::ChronoDateTime(v) => box_to_opt_ref!(v),
1104            _ => panic!("not Value::ChronoDateTime"),
1105        }
1106    }
1107}
1108
1109#[cfg(feature = "with-time")]
1110impl Value {
1111    pub fn is_time_date_time(&self) -> bool {
1112        matches!(self, Self::TimeDateTime(_))
1113    }
1114
1115    pub fn as_ref_time_date_time(&self) -> Option<&PrimitiveDateTime> {
1116        match self {
1117            Self::TimeDateTime(v) => box_to_opt_ref!(v),
1118            _ => panic!("not Value::TimeDateTime"),
1119        }
1120    }
1121}
1122
1123#[cfg(feature = "with-chrono")]
1124impl Value {
1125    pub fn is_chrono_date_time_utc(&self) -> bool {
1126        matches!(self, Self::ChronoDateTimeUtc(_))
1127    }
1128
1129    pub fn as_ref_chrono_date_time_utc(&self) -> Option<&DateTime<Utc>> {
1130        match self {
1131            Self::ChronoDateTimeUtc(v) => box_to_opt_ref!(v),
1132            _ => panic!("not Value::ChronoDateTimeUtc"),
1133        }
1134    }
1135}
1136
1137#[cfg(feature = "with-chrono")]
1138impl Value {
1139    pub fn is_chrono_date_time_local(&self) -> bool {
1140        matches!(self, Self::ChronoDateTimeLocal(_))
1141    }
1142
1143    pub fn as_ref_chrono_date_time_local(&self) -> Option<&DateTime<Local>> {
1144        match self {
1145            Self::ChronoDateTimeLocal(v) => box_to_opt_ref!(v),
1146            _ => panic!("not Value::ChronoDateTimeLocal"),
1147        }
1148    }
1149}
1150
1151#[cfg(feature = "with-chrono")]
1152impl Value {
1153    pub fn is_chrono_date_time_with_time_zone(&self) -> bool {
1154        matches!(self, Self::ChronoDateTimeWithTimeZone(_))
1155    }
1156
1157    pub fn as_ref_chrono_date_time_with_time_zone(&self) -> Option<&DateTime<FixedOffset>> {
1158        match self {
1159            Self::ChronoDateTimeWithTimeZone(v) => box_to_opt_ref!(v),
1160            _ => panic!("not Value::ChronoDateTimeWithTimeZone"),
1161        }
1162    }
1163}
1164
1165#[cfg(feature = "with-time")]
1166impl Value {
1167    pub fn is_time_date_time_with_time_zone(&self) -> bool {
1168        matches!(self, Self::TimeDateTimeWithTimeZone(_))
1169    }
1170
1171    pub fn as_ref_time_date_time_with_time_zone(&self) -> Option<&OffsetDateTime> {
1172        match self {
1173            Self::TimeDateTimeWithTimeZone(v) => box_to_opt_ref!(v),
1174            _ => panic!("not Value::TimeDateTimeWithTimeZone"),
1175        }
1176    }
1177}
1178
1179#[cfg(feature = "with-chrono")]
1180impl Value {
1181    pub fn chrono_as_naive_utc_in_string(&self) -> Option<String> {
1182        match self {
1183            Self::ChronoDate(v) => v.as_ref().map(|v| v.to_string()),
1184            Self::ChronoTime(v) => v.as_ref().map(|v| v.to_string()),
1185            Self::ChronoDateTime(v) => v.as_ref().map(|v| v.to_string()),
1186            Self::ChronoDateTimeUtc(v) => v.as_ref().map(|v| v.naive_utc().to_string()),
1187            Self::ChronoDateTimeLocal(v) => v.as_ref().map(|v| v.naive_utc().to_string()),
1188            Self::ChronoDateTimeWithTimeZone(v) => v.as_ref().map(|v| v.naive_utc().to_string()),
1189            _ => panic!("not chrono Value"),
1190        }
1191    }
1192}
1193
1194#[cfg(feature = "with-time")]
1195impl Value {
1196    pub fn time_as_naive_utc_in_string(&self) -> Option<String> {
1197        match self {
1198            Self::TimeDate(v) => v
1199                .as_ref()
1200                .and_then(|v| v.format(time_format::FORMAT_DATE).ok()),
1201            Self::TimeTime(v) => v
1202                .as_ref()
1203                .and_then(|v| v.format(time_format::FORMAT_TIME).ok()),
1204            Self::TimeDateTime(v) => v
1205                .as_ref()
1206                .and_then(|v| v.format(time_format::FORMAT_DATETIME).ok()),
1207            Self::TimeDateTimeWithTimeZone(v) => v.as_ref().and_then(|v| {
1208                v.to_offset(time::macros::offset!(UTC))
1209                    .format(time_format::FORMAT_DATETIME_TZ)
1210                    .ok()
1211            }),
1212            _ => panic!("not time Value"),
1213        }
1214    }
1215}
1216
1217#[cfg(feature = "with-rust_decimal")]
1218impl Value {
1219    pub fn is_decimal(&self) -> bool {
1220        matches!(self, Self::Decimal(_))
1221    }
1222
1223    pub fn as_ref_decimal(&self) -> Option<&Decimal> {
1224        match self {
1225            Self::Decimal(v) => box_to_opt_ref!(v),
1226            _ => panic!("not Value::Decimal"),
1227        }
1228    }
1229
1230    pub fn decimal_to_f64(&self) -> Option<f64> {
1231        use rust_decimal::prelude::ToPrimitive;
1232
1233        self.as_ref_decimal().map(|d| d.to_f64().unwrap())
1234    }
1235}
1236
1237#[cfg(feature = "with-bigdecimal")]
1238impl Value {
1239    pub fn is_big_decimal(&self) -> bool {
1240        matches!(self, Self::BigDecimal(_))
1241    }
1242
1243    pub fn as_ref_big_decimal(&self) -> Option<&BigDecimal> {
1244        match self {
1245            Self::BigDecimal(v) => box_to_opt_ref!(v),
1246            _ => panic!("not Value::BigDecimal"),
1247        }
1248    }
1249
1250    pub fn big_decimal_to_f64(&self) -> Option<f64> {
1251        use bigdecimal::ToPrimitive;
1252        self.as_ref_big_decimal().map(|d| d.to_f64().unwrap())
1253    }
1254}
1255
1256#[cfg(feature = "with-uuid")]
1257impl Value {
1258    pub fn is_uuid(&self) -> bool {
1259        matches!(self, Self::Uuid(_))
1260    }
1261    pub fn as_ref_uuid(&self) -> Option<&Uuid> {
1262        match self {
1263            Self::Uuid(v) => box_to_opt_ref!(v),
1264            _ => panic!("not Value::Uuid"),
1265        }
1266    }
1267}
1268
1269#[cfg(feature = "postgres-array")]
1270impl Value {
1271    pub fn is_array(&self) -> bool {
1272        matches!(self, Self::Array(_, _))
1273    }
1274
1275    pub fn as_ref_array(&self) -> Option<&Vec<Value>> {
1276        match self {
1277            Self::Array(_, v) => box_to_opt_ref!(v),
1278            _ => panic!("not Value::Array"),
1279        }
1280    }
1281}
1282
1283#[cfg(feature = "with-ipnetwork")]
1284impl Value {
1285    pub fn is_ipnetwork(&self) -> bool {
1286        matches!(self, Self::IpNetwork(_))
1287    }
1288
1289    pub fn as_ref_ipnetwork(&self) -> Option<&IpNetwork> {
1290        match self {
1291            Self::IpNetwork(v) => box_to_opt_ref!(v),
1292            _ => panic!("not Value::IpNetwork"),
1293        }
1294    }
1295
1296    pub fn as_ipaddr(&self) -> Option<IpAddr> {
1297        match self {
1298            Self::IpNetwork(v) => v.clone().map(|v| v.network()),
1299            _ => panic!("not Value::IpNetwork"),
1300        }
1301    }
1302}
1303
1304#[cfg(feature = "with-mac_address")]
1305impl Value {
1306    pub fn is_mac_address(&self) -> bool {
1307        matches!(self, Self::MacAddress(_))
1308    }
1309
1310    pub fn as_ref_mac_address(&self) -> Option<&MacAddress> {
1311        match self {
1312            Self::MacAddress(v) => box_to_opt_ref!(v),
1313            _ => panic!("not Value::MacAddress"),
1314        }
1315    }
1316}
1317
1318impl IntoIterator for ValueTuple {
1319    type Item = Value;
1320    type IntoIter = std::vec::IntoIter<Self::Item>;
1321
1322    fn into_iter(self) -> Self::IntoIter {
1323        match self {
1324            ValueTuple::One(v) => vec![v].into_iter(),
1325            ValueTuple::Two(v, w) => vec![v, w].into_iter(),
1326            ValueTuple::Three(u, v, w) => vec![u, v, w].into_iter(),
1327            ValueTuple::Many(vec) => vec.into_iter(),
1328        }
1329    }
1330}
1331
1332impl IntoValueTuple for ValueTuple {
1333    fn into_value_tuple(self) -> ValueTuple {
1334        self
1335    }
1336}
1337
1338impl<V> IntoValueTuple for V
1339where
1340    V: Into<Value>,
1341{
1342    fn into_value_tuple(self) -> ValueTuple {
1343        ValueTuple::One(self.into())
1344    }
1345}
1346
1347impl<V, W> IntoValueTuple for (V, W)
1348where
1349    V: Into<Value>,
1350    W: Into<Value>,
1351{
1352    fn into_value_tuple(self) -> ValueTuple {
1353        ValueTuple::Two(self.0.into(), self.1.into())
1354    }
1355}
1356
1357impl<U, V, W> IntoValueTuple for (U, V, W)
1358where
1359    U: Into<Value>,
1360    V: Into<Value>,
1361    W: Into<Value>,
1362{
1363    fn into_value_tuple(self) -> ValueTuple {
1364        ValueTuple::Three(self.0.into(), self.1.into(), self.2.into())
1365    }
1366}
1367
1368macro_rules! impl_into_value_tuple {
1369    ( $($idx:tt : $T:ident),+ $(,)? ) => {
1370        impl< $($T),+ > IntoValueTuple for ( $($T),+ )
1371        where
1372            $($T: Into<Value>),+
1373        {
1374            fn into_value_tuple(self) -> ValueTuple {
1375                ValueTuple::Many(vec![
1376                    $(self.$idx.into()),+
1377                ])
1378            }
1379        }
1380    };
1381}
1382
1383#[rustfmt::skip]
1384mod impl_into_value_tuple {
1385    use super::*;
1386
1387    impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3);
1388    impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4);
1389    impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4, 5:T5);
1390    impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4, 5:T5, 6:T6);
1391    impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4, 5:T5, 6:T6, 7:T7);
1392    impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4, 5:T5, 6:T6, 7:T7, 8:T8);
1393    impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4, 5:T5, 6:T6, 7:T7, 8:T8, 9:T9);
1394    impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4, 5:T5, 6:T6, 7:T7, 8:T8, 9:T9, 10:T10);
1395    impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4, 5:T5, 6:T6, 7:T7, 8:T8, 9:T9, 10:T10, 11:T11);
1396}
1397
1398impl<V> FromValueTuple for V
1399where
1400    V: Into<Value> + ValueType,
1401{
1402    fn from_value_tuple<I>(i: I) -> Self
1403    where
1404        I: IntoValueTuple,
1405    {
1406        match i.into_value_tuple() {
1407            ValueTuple::One(u) => u.unwrap(),
1408            _ => panic!("not ValueTuple::One"),
1409        }
1410    }
1411}
1412
1413impl<V, W> FromValueTuple for (V, W)
1414where
1415    V: Into<Value> + ValueType,
1416    W: Into<Value> + ValueType,
1417{
1418    fn from_value_tuple<I>(i: I) -> Self
1419    where
1420        I: IntoValueTuple,
1421    {
1422        match i.into_value_tuple() {
1423            ValueTuple::Two(v, w) => (v.unwrap(), w.unwrap()),
1424            _ => panic!("not ValueTuple::Two"),
1425        }
1426    }
1427}
1428
1429impl<U, V, W> FromValueTuple for (U, V, W)
1430where
1431    U: Into<Value> + ValueType,
1432    V: Into<Value> + ValueType,
1433    W: Into<Value> + ValueType,
1434{
1435    fn from_value_tuple<I>(i: I) -> Self
1436    where
1437        I: IntoValueTuple,
1438    {
1439        match i.into_value_tuple() {
1440            ValueTuple::Three(u, v, w) => (u.unwrap(), v.unwrap(), w.unwrap()),
1441            _ => panic!("not ValueTuple::Three"),
1442        }
1443    }
1444}
1445
1446macro_rules! impl_from_value_tuple {
1447    ( $len:expr, $($T:ident),+ $(,)? ) => {
1448        impl< $($T),+ > FromValueTuple for ( $($T),+ )
1449        where
1450            $($T: Into<Value> + ValueType),+
1451        {
1452            fn from_value_tuple<Z>(i: Z) -> Self
1453            where
1454                Z: IntoValueTuple,
1455            {
1456                match i.into_value_tuple() {
1457                    ValueTuple::Many(vec) if vec.len() == $len => {
1458                        let mut iter = vec.into_iter();
1459                        (
1460                            $(<$T as ValueType>::unwrap(iter.next().unwrap())),+
1461                        )
1462                    }
1463                    _ => panic!("not ValueTuple::Many with length of {}", $len),
1464                }
1465            }
1466        }
1467    };
1468}
1469
1470#[rustfmt::skip]
1471mod impl_from_value_tuple {
1472    use super::*;
1473
1474    impl_from_value_tuple!( 4, T0, T1, T2, T3);
1475    impl_from_value_tuple!( 5, T0, T1, T2, T3, T4);
1476    impl_from_value_tuple!( 6, T0, T1, T2, T3, T4, T5);
1477    impl_from_value_tuple!( 7, T0, T1, T2, T3, T4, T5, T6);
1478    impl_from_value_tuple!( 8, T0, T1, T2, T3, T4, T5, T6, T7);
1479    impl_from_value_tuple!( 9, T0, T1, T2, T3, T4, T5, T6, T7, T8);
1480    impl_from_value_tuple!(10, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9);
1481    impl_from_value_tuple!(11, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
1482    impl_from_value_tuple!(12, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
1483}
1484
1485/// Convert value to json value
1486#[allow(clippy::many_single_char_names)]
1487#[cfg(feature = "with-json")]
1488#[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
1489pub fn sea_value_to_json_value(value: &Value) -> Json {
1490    match value {
1491        Value::Bool(None)
1492        | Value::TinyInt(None)
1493        | Value::SmallInt(None)
1494        | Value::Int(None)
1495        | Value::BigInt(None)
1496        | Value::TinyUnsigned(None)
1497        | Value::SmallUnsigned(None)
1498        | Value::Unsigned(None)
1499        | Value::BigUnsigned(None)
1500        | Value::Float(None)
1501        | Value::Double(None)
1502        | Value::String(None)
1503        | Value::Char(None)
1504        | Value::Bytes(None)
1505        | Value::Json(None) => Json::Null,
1506        #[cfg(feature = "with-rust_decimal")]
1507        Value::Decimal(None) => Json::Null,
1508        #[cfg(feature = "with-bigdecimal")]
1509        Value::BigDecimal(None) => Json::Null,
1510        #[cfg(feature = "with-uuid")]
1511        Value::Uuid(None) => Json::Null,
1512        #[cfg(feature = "postgres-array")]
1513        Value::Array(_, None) => Json::Null,
1514        #[cfg(feature = "postgres-vector")]
1515        Value::Vector(None) => Json::Null,
1516        #[cfg(feature = "with-ipnetwork")]
1517        Value::IpNetwork(None) => Json::Null,
1518        #[cfg(feature = "with-mac_address")]
1519        Value::MacAddress(None) => Json::Null,
1520        Value::Bool(Some(b)) => Json::Bool(*b),
1521        Value::TinyInt(Some(v)) => (*v).into(),
1522        Value::SmallInt(Some(v)) => (*v).into(),
1523        Value::Int(Some(v)) => (*v).into(),
1524        Value::BigInt(Some(v)) => (*v).into(),
1525        Value::TinyUnsigned(Some(v)) => (*v).into(),
1526        Value::SmallUnsigned(Some(v)) => (*v).into(),
1527        Value::Unsigned(Some(v)) => (*v).into(),
1528        Value::BigUnsigned(Some(v)) => (*v).into(),
1529        Value::Float(Some(v)) => (*v).into(),
1530        Value::Double(Some(v)) => (*v).into(),
1531        Value::String(Some(s)) => Json::String(s.as_ref().clone()),
1532        Value::Char(Some(v)) => Json::String(v.to_string()),
1533        Value::Bytes(Some(s)) => Json::String(from_utf8(s).unwrap().to_string()),
1534        Value::Json(Some(v)) => v.as_ref().clone(),
1535        #[cfg(feature = "with-chrono")]
1536        Value::ChronoDate(_) => CommonSqlQueryBuilder.value_to_string(value).into(),
1537        #[cfg(feature = "with-chrono")]
1538        Value::ChronoTime(_) => CommonSqlQueryBuilder.value_to_string(value).into(),
1539        #[cfg(feature = "with-chrono")]
1540        Value::ChronoDateTime(_) => CommonSqlQueryBuilder.value_to_string(value).into(),
1541        #[cfg(feature = "with-chrono")]
1542        Value::ChronoDateTimeWithTimeZone(_) => CommonSqlQueryBuilder.value_to_string(value).into(),
1543        #[cfg(feature = "with-chrono")]
1544        Value::ChronoDateTimeUtc(_) => CommonSqlQueryBuilder.value_to_string(value).into(),
1545        #[cfg(feature = "with-chrono")]
1546        Value::ChronoDateTimeLocal(_) => CommonSqlQueryBuilder.value_to_string(value).into(),
1547        #[cfg(feature = "with-time")]
1548        Value::TimeDate(_) => CommonSqlQueryBuilder.value_to_string(value).into(),
1549        #[cfg(feature = "with-time")]
1550        Value::TimeTime(_) => CommonSqlQueryBuilder.value_to_string(value).into(),
1551        #[cfg(feature = "with-time")]
1552        Value::TimeDateTime(_) => CommonSqlQueryBuilder.value_to_string(value).into(),
1553        #[cfg(feature = "with-time")]
1554        Value::TimeDateTimeWithTimeZone(_) => CommonSqlQueryBuilder.value_to_string(value).into(),
1555        #[cfg(feature = "with-rust_decimal")]
1556        Value::Decimal(Some(v)) => {
1557            use rust_decimal::prelude::ToPrimitive;
1558            v.as_ref().to_f64().unwrap().into()
1559        }
1560        #[cfg(feature = "with-bigdecimal")]
1561        Value::BigDecimal(Some(v)) => {
1562            use bigdecimal::ToPrimitive;
1563            v.as_ref().to_f64().unwrap().into()
1564        }
1565        #[cfg(feature = "with-uuid")]
1566        Value::Uuid(Some(v)) => Json::String(v.to_string()),
1567        #[cfg(feature = "postgres-array")]
1568        Value::Array(_, Some(v)) => {
1569            Json::Array(v.as_ref().iter().map(sea_value_to_json_value).collect())
1570        }
1571        #[cfg(feature = "postgres-vector")]
1572        Value::Vector(Some(v)) => Json::Array(v.as_slice().iter().map(|&v| v.into()).collect()),
1573        #[cfg(feature = "with-ipnetwork")]
1574        Value::IpNetwork(Some(_)) => CommonSqlQueryBuilder.value_to_string(value).into(),
1575        #[cfg(feature = "with-mac_address")]
1576        Value::MacAddress(Some(_)) => CommonSqlQueryBuilder.value_to_string(value).into(),
1577    }
1578}
1579
1580impl Values {
1581    pub fn iter(&self) -> impl Iterator<Item = &Value> {
1582        self.0.iter()
1583    }
1584}
1585
1586impl IntoIterator for Values {
1587    type Item = Value;
1588    type IntoIter = std::vec::IntoIter<Self::Item>;
1589
1590    fn into_iter(self) -> Self::IntoIter {
1591        self.0.into_iter()
1592    }
1593}
1594
1595#[cfg(test)]
1596mod tests {
1597    use super::*;
1598    use pretty_assertions::assert_eq;
1599
1600    #[test]
1601    fn test_value() {
1602        macro_rules! test_value {
1603            ( $type: ty, $val: literal ) => {
1604                let val: $type = $val;
1605                let v: Value = val.into();
1606                let out: $type = v.unwrap();
1607                assert_eq!(out, val);
1608            };
1609        }
1610
1611        test_value!(u8, 255);
1612        test_value!(u16, 65535);
1613        test_value!(i8, 127);
1614        test_value!(i16, 32767);
1615        test_value!(i32, 1073741824);
1616        test_value!(i64, 8589934592);
1617    }
1618
1619    #[test]
1620    fn test_option_value() {
1621        macro_rules! test_some_value {
1622            ( $type: ty, $val: literal ) => {
1623                let val: Option<$type> = Some($val);
1624                let v: Value = val.into();
1625                let out: $type = v.unwrap();
1626                assert_eq!(out, val.unwrap());
1627            };
1628        }
1629
1630        macro_rules! test_none {
1631            ( $type: ty, $name: ident ) => {
1632                let val: Option<$type> = None;
1633                let v: Value = val.into();
1634                assert_eq!(v, Value::$name(None));
1635            };
1636        }
1637
1638        test_some_value!(u8, 255);
1639        test_some_value!(u16, 65535);
1640        test_some_value!(i8, 127);
1641        test_some_value!(i16, 32767);
1642        test_some_value!(i32, 1073741824);
1643        test_some_value!(i64, 8589934592);
1644
1645        test_none!(u8, TinyUnsigned);
1646        test_none!(u16, SmallUnsigned);
1647        test_none!(i8, TinyInt);
1648        test_none!(i16, SmallInt);
1649        test_none!(i32, Int);
1650        test_none!(i64, BigInt);
1651    }
1652
1653    #[test]
1654    fn test_cow_value() {
1655        let val: Cow<str> = "hello".into();
1656        let val2 = val.clone();
1657        let v: Value = val.into();
1658        let out: Cow<str> = v.unwrap();
1659        assert_eq!(out, val2);
1660    }
1661
1662    #[test]
1663    fn test_box_value() {
1664        let val: String = "hello".to_owned();
1665        let v: Value = val.clone().into();
1666        let out: String = v.unwrap();
1667        assert_eq!(out, val);
1668    }
1669
1670    #[test]
1671    fn test_value_tuple() {
1672        assert_eq!(
1673            1i32.into_value_tuple(),
1674            ValueTuple::One(Value::Int(Some(1)))
1675        );
1676        assert_eq!(
1677            "b".into_value_tuple(),
1678            ValueTuple::One(Value::String(Some(Box::new("b".to_owned()))))
1679        );
1680        assert_eq!(
1681            (1i32, "b").into_value_tuple(),
1682            ValueTuple::Two(
1683                Value::Int(Some(1)),
1684                Value::String(Some(Box::new("b".to_owned())))
1685            )
1686        );
1687        assert_eq!(
1688            (1i32, 2.4f64, "b").into_value_tuple(),
1689            ValueTuple::Three(
1690                Value::Int(Some(1)),
1691                Value::Double(Some(2.4)),
1692                Value::String(Some(Box::new("b".to_owned())))
1693            )
1694        );
1695        assert_eq!(
1696            (1i32, 2.4f64, "b", 123u8).into_value_tuple(),
1697            ValueTuple::Many(vec![
1698                Value::Int(Some(1)),
1699                Value::Double(Some(2.4)),
1700                Value::String(Some(Box::new("b".to_owned()))),
1701                Value::TinyUnsigned(Some(123))
1702            ])
1703        );
1704        assert_eq!(
1705            (1i32, 2.4f64, "b", 123u8, 456u16).into_value_tuple(),
1706            ValueTuple::Many(vec![
1707                Value::Int(Some(1)),
1708                Value::Double(Some(2.4)),
1709                Value::String(Some(Box::new("b".to_owned()))),
1710                Value::TinyUnsigned(Some(123)),
1711                Value::SmallUnsigned(Some(456))
1712            ])
1713        );
1714        assert_eq!(
1715            (1i32, 2.4f64, "b", 123u8, 456u16, 789u32).into_value_tuple(),
1716            ValueTuple::Many(vec![
1717                Value::Int(Some(1)),
1718                Value::Double(Some(2.4)),
1719                Value::String(Some(Box::new("b".to_owned()))),
1720                Value::TinyUnsigned(Some(123)),
1721                Value::SmallUnsigned(Some(456)),
1722                Value::Unsigned(Some(789))
1723            ])
1724        );
1725    }
1726
1727    #[test]
1728    #[allow(clippy::clone_on_copy)]
1729    fn test_from_value_tuple() {
1730        let mut val = 1i32;
1731        let original = val.clone();
1732        val = FromValueTuple::from_value_tuple(val);
1733        assert_eq!(val, original);
1734
1735        let mut val = "b".to_owned();
1736        let original = val.clone();
1737        val = FromValueTuple::from_value_tuple(val);
1738        assert_eq!(val, original);
1739
1740        let mut val = (1i32, "b".to_owned());
1741        let original = val.clone();
1742        val = FromValueTuple::from_value_tuple(val);
1743        assert_eq!(val, original);
1744
1745        let mut val = (1i32, 2.4f64, "b".to_owned());
1746        let original = val.clone();
1747        val = FromValueTuple::from_value_tuple(val);
1748        assert_eq!(val, original);
1749
1750        let mut val = (1i32, 2.4f64, "b".to_owned(), 123u8);
1751        let original = val.clone();
1752        val = FromValueTuple::from_value_tuple(val);
1753        assert_eq!(val, original);
1754
1755        let mut val = (1i32, 2.4f64, "b".to_owned(), 123u8, 456u16);
1756        let original = val.clone();
1757        val = FromValueTuple::from_value_tuple(val);
1758        assert_eq!(val, original);
1759
1760        let mut val = (1i32, 2.4f64, "b".to_owned(), 123u8, 456u16, 789u32);
1761        let original = val.clone();
1762        val = FromValueTuple::from_value_tuple(val);
1763        assert_eq!(val, original);
1764    }
1765
1766    #[test]
1767    fn test_value_tuple_iter() {
1768        let mut iter = (1i32).into_value_tuple().into_iter();
1769        assert_eq!(iter.next().unwrap(), Value::Int(Some(1)));
1770        assert_eq!(iter.next(), None);
1771
1772        let mut iter = (1i32, 2.4f64).into_value_tuple().into_iter();
1773        assert_eq!(iter.next().unwrap(), Value::Int(Some(1)));
1774        assert_eq!(iter.next().unwrap(), Value::Double(Some(2.4)));
1775        assert_eq!(iter.next(), None);
1776
1777        let mut iter = (1i32, 2.4f64, "b").into_value_tuple().into_iter();
1778        assert_eq!(iter.next().unwrap(), Value::Int(Some(1)));
1779        assert_eq!(iter.next().unwrap(), Value::Double(Some(2.4)));
1780        assert_eq!(
1781            iter.next().unwrap(),
1782            Value::String(Some(Box::new("b".to_owned())))
1783        );
1784        assert_eq!(iter.next(), None);
1785
1786        let mut iter = (1i32, 2.4f64, "b", 123u8).into_value_tuple().into_iter();
1787        assert_eq!(iter.next().unwrap(), Value::Int(Some(1)));
1788        assert_eq!(iter.next().unwrap(), Value::Double(Some(2.4)));
1789        assert_eq!(
1790            iter.next().unwrap(),
1791            Value::String(Some(Box::new("b".to_owned())))
1792        );
1793        assert_eq!(iter.next().unwrap(), Value::TinyUnsigned(Some(123)));
1794        assert_eq!(iter.next(), None);
1795
1796        let mut iter = (1i32, 2.4f64, "b", 123u8, 456u16)
1797            .into_value_tuple()
1798            .into_iter();
1799        assert_eq!(iter.next().unwrap(), Value::Int(Some(1)));
1800        assert_eq!(iter.next().unwrap(), Value::Double(Some(2.4)));
1801        assert_eq!(
1802            iter.next().unwrap(),
1803            Value::String(Some(Box::new("b".to_owned())))
1804        );
1805        assert_eq!(iter.next().unwrap(), Value::TinyUnsigned(Some(123)));
1806        assert_eq!(iter.next().unwrap(), Value::SmallUnsigned(Some(456)));
1807        assert_eq!(iter.next(), None);
1808
1809        let mut iter = (1i32, 2.4f64, "b", 123u8, 456u16, 789u32)
1810            .into_value_tuple()
1811            .into_iter();
1812        assert_eq!(iter.next().unwrap(), Value::Int(Some(1)));
1813        assert_eq!(iter.next().unwrap(), Value::Double(Some(2.4)));
1814        assert_eq!(
1815            iter.next().unwrap(),
1816            Value::String(Some(Box::new("b".to_owned())))
1817        );
1818        assert_eq!(iter.next().unwrap(), Value::TinyUnsigned(Some(123)));
1819        assert_eq!(iter.next().unwrap(), Value::SmallUnsigned(Some(456)));
1820        assert_eq!(iter.next().unwrap(), Value::Unsigned(Some(789)));
1821        assert_eq!(iter.next(), None);
1822    }
1823
1824    #[test]
1825    #[cfg(feature = "with-json")]
1826    fn test_json_value() {
1827        let json = serde_json::json! {{
1828            "a": 25.0,
1829            "b": "hello",
1830        }};
1831        let value: Value = json.clone().into();
1832        let out: Json = value.unwrap();
1833        assert_eq!(out, json);
1834    }
1835
1836    #[test]
1837    #[cfg(feature = "with-chrono")]
1838    fn test_chrono_value() {
1839        let timestamp = NaiveDate::from_ymd_opt(2020, 1, 1)
1840            .unwrap()
1841            .and_hms_opt(2, 2, 2)
1842            .unwrap();
1843        let value: Value = timestamp.into();
1844        let out: NaiveDateTime = value.unwrap();
1845        assert_eq!(out, timestamp);
1846    }
1847
1848    #[test]
1849    #[cfg(feature = "with-chrono")]
1850    fn test_chrono_utc_value() {
1851        let timestamp = DateTime::<Utc>::from_naive_utc_and_offset(
1852            NaiveDate::from_ymd_opt(2022, 1, 2)
1853                .unwrap()
1854                .and_hms_opt(3, 4, 5)
1855                .unwrap(),
1856            Utc,
1857        );
1858        let value: Value = timestamp.into();
1859        let out: DateTime<Utc> = value.unwrap();
1860        assert_eq!(out, timestamp);
1861    }
1862
1863    #[test]
1864    #[cfg(feature = "with-chrono")]
1865    fn test_chrono_local_value() {
1866        let timestamp_utc = DateTime::<Utc>::from_naive_utc_and_offset(
1867            NaiveDate::from_ymd_opt(2022, 1, 2)
1868                .unwrap()
1869                .and_hms_opt(3, 4, 5)
1870                .unwrap(),
1871            Utc,
1872        );
1873        let timestamp_local: DateTime<Local> = timestamp_utc.into();
1874        let value: Value = timestamp_local.into();
1875        let out: DateTime<Local> = value.unwrap();
1876        assert_eq!(out, timestamp_local);
1877    }
1878
1879    #[test]
1880    #[cfg(feature = "with-chrono")]
1881    fn test_chrono_timezone_value() {
1882        let timestamp = DateTime::parse_from_rfc3339("2020-01-01T02:02:02+08:00").unwrap();
1883        let value: Value = timestamp.into();
1884        let out: DateTime<FixedOffset> = value.unwrap();
1885        assert_eq!(out, timestamp);
1886    }
1887
1888    #[test]
1889    #[cfg(feature = "with-chrono")]
1890    fn test_chrono_query() {
1891        use crate::*;
1892
1893        let string = "2020-01-01T02:02:02+08:00";
1894        let timestamp = DateTime::parse_from_rfc3339(string).unwrap();
1895
1896        let query = Query::select().expr(timestamp).to_owned();
1897
1898        let formatted = "2020-01-01 02:02:02 +08:00";
1899
1900        assert_eq!(
1901            query.to_string(MysqlQueryBuilder),
1902            format!("SELECT '{formatted}'")
1903        );
1904        assert_eq!(
1905            query.to_string(PostgresQueryBuilder),
1906            format!("SELECT '{formatted}'")
1907        );
1908        assert_eq!(
1909            query.to_string(SqliteQueryBuilder),
1910            format!("SELECT '{formatted}'")
1911        );
1912    }
1913
1914    #[test]
1915    #[cfg(feature = "with-time")]
1916    fn test_time_value() {
1917        use time::macros::{date, time};
1918        let timestamp = date!(2020 - 01 - 01).with_time(time!(2:2:2));
1919        let value: Value = timestamp.into();
1920        let out: PrimitiveDateTime = value.unwrap();
1921        assert_eq!(out, timestamp);
1922    }
1923
1924    #[test]
1925    #[cfg(feature = "with-time")]
1926    fn test_time_utc_value() {
1927        use time::macros::{date, time};
1928        let timestamp = date!(2022 - 01 - 02).with_time(time!(3:04:05)).assume_utc();
1929        let value: Value = timestamp.into();
1930        let out: OffsetDateTime = value.unwrap();
1931        assert_eq!(out, timestamp);
1932    }
1933
1934    #[test]
1935    #[cfg(feature = "with-time")]
1936    fn test_time_local_value() {
1937        use time::macros::{date, offset, time};
1938        let timestamp_utc = date!(2022 - 01 - 02).with_time(time!(3:04:05)).assume_utc();
1939        let timestamp_local: OffsetDateTime = timestamp_utc.to_offset(offset!(+3));
1940        let value: Value = timestamp_local.into();
1941        let out: OffsetDateTime = value.unwrap();
1942        assert_eq!(out, timestamp_local);
1943    }
1944
1945    #[test]
1946    #[cfg(feature = "with-time")]
1947    fn test_time_timezone_value() {
1948        use time::macros::{date, offset, time};
1949        let timestamp = date!(2022 - 01 - 02)
1950            .with_time(time!(3:04:05))
1951            .assume_offset(offset!(+8));
1952        let value: Value = timestamp.into();
1953        let out: OffsetDateTime = value.unwrap();
1954        assert_eq!(out, timestamp);
1955    }
1956
1957    #[test]
1958    #[cfg(feature = "with-time")]
1959    fn test_time_query() {
1960        use crate::*;
1961        use time::macros::datetime;
1962
1963        let timestamp = datetime!(2020-01-01 02:02:02 +8);
1964        let query = Query::select().expr(timestamp).to_owned();
1965        let formatted = "2020-01-01 02:02:02.000000 +08:00";
1966
1967        assert_eq!(
1968            query.to_string(MysqlQueryBuilder),
1969            format!("SELECT '{formatted}'")
1970        );
1971        assert_eq!(
1972            query.to_string(PostgresQueryBuilder),
1973            format!("SELECT '{formatted}'")
1974        );
1975        assert_eq!(
1976            query.to_string(SqliteQueryBuilder),
1977            format!("SELECT '{formatted}'")
1978        );
1979    }
1980
1981    #[test]
1982    #[cfg(feature = "with-uuid")]
1983    fn test_uuid_value() {
1984        let uuid = Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8").unwrap();
1985        let value: Value = uuid.into();
1986        let out: Uuid = value.unwrap();
1987        assert_eq!(out, uuid);
1988
1989        let uuid_braced = uuid.braced();
1990        let value: Value = uuid_braced.into();
1991        let out: Uuid = value.unwrap();
1992        assert_eq!(out, uuid);
1993
1994        let uuid_hyphenated = uuid.hyphenated();
1995        let value: Value = uuid_hyphenated.into();
1996        let out: Uuid = value.unwrap();
1997        assert_eq!(out, uuid);
1998
1999        let uuid_simple = uuid.simple();
2000        let value: Value = uuid_simple.into();
2001        let out: Uuid = value.unwrap();
2002        assert_eq!(out, uuid);
2003
2004        let uuid_urn = uuid.urn();
2005        let value: Value = uuid_urn.into();
2006        let out: Uuid = value.unwrap();
2007        assert_eq!(out, uuid);
2008    }
2009
2010    #[test]
2011    #[cfg(feature = "with-rust_decimal")]
2012    fn test_decimal_value() {
2013        use std::str::FromStr;
2014
2015        let num = "2.02";
2016        let val = Decimal::from_str(num).unwrap();
2017        let v: Value = val.into();
2018        let out: Decimal = v.unwrap();
2019        assert_eq!(out.to_string(), num);
2020    }
2021
2022    #[test]
2023    #[cfg(feature = "postgres-array")]
2024    fn test_array_value() {
2025        let array = vec![1, 2, 3, 4, 5];
2026        let v: Value = array.into();
2027        let out: Vec<i32> = v.unwrap();
2028        assert_eq!(out, vec![1, 2, 3, 4, 5]);
2029    }
2030
2031    #[test]
2032    #[cfg(feature = "postgres-array")]
2033    fn test_option_array_value() {
2034        let v: Value = Value::Array(ArrayType::Int, None);
2035        let out: Option<Vec<i32>> = v.unwrap();
2036        assert_eq!(out, None);
2037    }
2038}
2039
2040#[cfg(feature = "hashable-value")]
2041mod hashable_value {
2042    use super::*;
2043    use ordered_float::OrderedFloat;
2044    use std::{
2045        hash::{Hash, Hasher},
2046        mem,
2047    };
2048
2049    impl PartialEq for Value {
2050        fn eq(&self, other: &Self) -> bool {
2051            match (self, other) {
2052                (Self::Bool(l), Self::Bool(r)) => l == r,
2053                (Self::TinyInt(l), Self::TinyInt(r)) => l == r,
2054                (Self::SmallInt(l), Self::SmallInt(r)) => l == r,
2055                (Self::Int(l), Self::Int(r)) => l == r,
2056                (Self::BigInt(l), Self::BigInt(r)) => l == r,
2057                (Self::TinyUnsigned(l), Self::TinyUnsigned(r)) => l == r,
2058                (Self::SmallUnsigned(l), Self::SmallUnsigned(r)) => l == r,
2059                (Self::Unsigned(l), Self::Unsigned(r)) => l == r,
2060                (Self::BigUnsigned(l), Self::BigUnsigned(r)) => l == r,
2061                (Self::Float(l), Self::Float(r)) => cmp_f32(l, r),
2062                (Self::Double(l), Self::Double(r)) => cmp_f64(l, r),
2063                (Self::String(l), Self::String(r)) => l == r,
2064                (Self::Char(l), Self::Char(r)) => l == r,
2065                (Self::Bytes(l), Self::Bytes(r)) => l == r,
2066
2067                #[cfg(feature = "with-json")]
2068                (Self::Json(l), Self::Json(r)) => cmp_json(l, r),
2069
2070                #[cfg(feature = "with-chrono")]
2071                (Self::ChronoDate(l), Self::ChronoDate(r)) => l == r,
2072                #[cfg(feature = "with-chrono")]
2073                (Self::ChronoTime(l), Self::ChronoTime(r)) => l == r,
2074                #[cfg(feature = "with-chrono")]
2075                (Self::ChronoDateTime(l), Self::ChronoDateTime(r)) => l == r,
2076                #[cfg(feature = "with-chrono")]
2077                (Self::ChronoDateTimeUtc(l), Self::ChronoDateTimeUtc(r)) => l == r,
2078                #[cfg(feature = "with-chrono")]
2079                (Self::ChronoDateTimeLocal(l), Self::ChronoDateTimeLocal(r)) => l == r,
2080                #[cfg(feature = "with-chrono")]
2081                (Self::ChronoDateTimeWithTimeZone(l), Self::ChronoDateTimeWithTimeZone(r)) => {
2082                    l == r
2083                }
2084
2085                #[cfg(feature = "with-time")]
2086                (Self::TimeDate(l), Self::TimeDate(r)) => l == r,
2087                #[cfg(feature = "with-time")]
2088                (Self::TimeTime(l), Self::TimeTime(r)) => l == r,
2089                #[cfg(feature = "with-time")]
2090                (Self::TimeDateTime(l), Self::TimeDateTime(r)) => l == r,
2091                #[cfg(feature = "with-time")]
2092                (Self::TimeDateTimeWithTimeZone(l), Self::TimeDateTimeWithTimeZone(r)) => l == r,
2093
2094                #[cfg(feature = "with-uuid")]
2095                (Self::Uuid(l), Self::Uuid(r)) => l == r,
2096
2097                #[cfg(feature = "with-rust_decimal")]
2098                (Self::Decimal(l), Self::Decimal(r)) => l == r,
2099
2100                #[cfg(feature = "with-bigdecimal")]
2101                (Self::BigDecimal(l), Self::BigDecimal(r)) => l == r,
2102
2103                #[cfg(feature = "postgres-array")]
2104                (Self::Array(ty_l, values_l), Self::Array(ty_r, values_r)) => {
2105                    ty_l == ty_r && values_l == values_r
2106                }
2107
2108                #[cfg(feature = "postgres-vector")]
2109                (Self::Vector(l), Self::Vector(r)) => cmp_vector(l, r),
2110
2111                #[cfg(feature = "with-ipnetwork")]
2112                (Self::IpNetwork(l), Self::IpNetwork(r)) => l == r,
2113
2114                #[cfg(feature = "with-mac_address")]
2115                (Self::MacAddress(l), Self::MacAddress(r)) => l == r,
2116
2117                _ => false,
2118            }
2119        }
2120    }
2121
2122    impl Eq for Value {}
2123
2124    impl Hash for Value {
2125        fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
2126            mem::discriminant(self).hash(state);
2127            match self {
2128                Value::Bool(v) => v.hash(state),
2129                Value::TinyInt(v) => v.hash(state),
2130                Value::SmallInt(v) => v.hash(state),
2131                Value::Int(v) => v.hash(state),
2132                Value::BigInt(v) => v.hash(state),
2133                Value::TinyUnsigned(v) => v.hash(state),
2134                Value::SmallUnsigned(v) => v.hash(state),
2135                Value::Unsigned(v) => v.hash(state),
2136                Value::BigUnsigned(v) => v.hash(state),
2137                Value::Float(v) => hash_f32(v, state),
2138                Value::Double(v) => hash_f64(v, state),
2139                Value::String(v) => v.hash(state),
2140                Value::Char(v) => v.hash(state),
2141                Value::Bytes(v) => v.hash(state),
2142
2143                #[cfg(feature = "with-json")]
2144                Value::Json(value) => hash_json(value, state),
2145
2146                #[cfg(feature = "with-chrono")]
2147                Value::ChronoDate(naive_date) => naive_date.hash(state),
2148                #[cfg(feature = "with-chrono")]
2149                Value::ChronoTime(naive_time) => naive_time.hash(state),
2150                #[cfg(feature = "with-chrono")]
2151                Value::ChronoDateTime(naive_date_time) => naive_date_time.hash(state),
2152                #[cfg(feature = "with-chrono")]
2153                Value::ChronoDateTimeUtc(date_time) => date_time.hash(state),
2154                #[cfg(feature = "with-chrono")]
2155                Value::ChronoDateTimeLocal(date_time) => date_time.hash(state),
2156                #[cfg(feature = "with-chrono")]
2157                Value::ChronoDateTimeWithTimeZone(date_time) => date_time.hash(state),
2158
2159                #[cfg(feature = "with-time")]
2160                Value::TimeDate(date) => date.hash(state),
2161                #[cfg(feature = "with-time")]
2162                Value::TimeTime(time) => time.hash(state),
2163                #[cfg(feature = "with-time")]
2164                Value::TimeDateTime(primitive_date_time) => primitive_date_time.hash(state),
2165                #[cfg(feature = "with-time")]
2166                Value::TimeDateTimeWithTimeZone(offset_date_time) => offset_date_time.hash(state),
2167
2168                #[cfg(feature = "with-uuid")]
2169                Value::Uuid(uuid) => uuid.hash(state),
2170
2171                #[cfg(feature = "with-rust_decimal")]
2172                Value::Decimal(decimal) => decimal.hash(state),
2173
2174                #[cfg(feature = "with-bigdecimal")]
2175                Value::BigDecimal(big_decimal) => big_decimal.hash(state),
2176
2177                #[cfg(feature = "postgres-array")]
2178                Value::Array(array_type, vec) => {
2179                    array_type.hash(state);
2180                    vec.hash(state);
2181                }
2182
2183                #[cfg(feature = "postgres-vector")]
2184                Value::Vector(vector) => hash_vector(vector, state),
2185
2186                #[cfg(feature = "with-ipnetwork")]
2187                Value::IpNetwork(ip_network) => ip_network.hash(state),
2188
2189                #[cfg(feature = "with-mac_address")]
2190                Value::MacAddress(mac_address) => mac_address.hash(state),
2191            }
2192        }
2193    }
2194
2195    fn hash_f32<H: Hasher>(v: &Option<f32>, state: &mut H) {
2196        match v {
2197            Some(v) => OrderedFloat(*v).hash(state),
2198            None => "null".hash(state),
2199        }
2200    }
2201
2202    fn hash_f64<H: Hasher>(v: &Option<f64>, state: &mut H) {
2203        match v {
2204            Some(v) => OrderedFloat(*v).hash(state),
2205            None => "null".hash(state),
2206        }
2207    }
2208
2209    fn cmp_f32(l: &Option<f32>, r: &Option<f32>) -> bool {
2210        match (l, r) {
2211            (Some(l), Some(r)) => OrderedFloat(*l).eq(&OrderedFloat(*r)),
2212            (None, None) => true,
2213            _ => false,
2214        }
2215    }
2216
2217    fn cmp_f64(l: &Option<f64>, r: &Option<f64>) -> bool {
2218        match (l, r) {
2219            (Some(l), Some(r)) => OrderedFloat(*l).eq(&OrderedFloat(*r)),
2220            (None, None) => true,
2221            _ => false,
2222        }
2223    }
2224
2225    #[cfg(feature = "with-json")]
2226    fn hash_json<H: Hasher>(v: &Option<Box<Json>>, state: &mut H) {
2227        match v {
2228            Some(v) => serde_json::to_string(v).unwrap().hash(state),
2229            None => "null".hash(state),
2230        }
2231    }
2232
2233    #[cfg(feature = "with-json")]
2234    fn cmp_json(l: &Option<Box<Json>>, r: &Option<Box<Json>>) -> bool {
2235        match (l, r) {
2236            (Some(l), Some(r)) => serde_json::to_string(l)
2237                .unwrap()
2238                .eq(&serde_json::to_string(r).unwrap()),
2239            (None, None) => true,
2240            _ => false,
2241        }
2242    }
2243
2244    #[cfg(feature = "postgres-vector")]
2245    fn hash_vector<H: Hasher>(v: &Option<Box<pgvector::Vector>>, state: &mut H) {
2246        match v {
2247            Some(v) => {
2248                for &value in v.as_slice().iter() {
2249                    hash_f32(&Some(value), state);
2250                }
2251            }
2252            None => "null".hash(state),
2253        }
2254    }
2255
2256    #[cfg(feature = "postgres-vector")]
2257    fn cmp_vector(l: &Option<Box<pgvector::Vector>>, r: &Option<Box<pgvector::Vector>>) -> bool {
2258        match (l, r) {
2259            (Some(l), Some(r)) => {
2260                let (l, r) = (l.as_slice(), r.as_slice());
2261                if l.len() != r.len() {
2262                    return false;
2263                }
2264                for (l, r) in l.iter().zip(r.iter()) {
2265                    if !cmp_f32(&Some(*l), &Some(*r)) {
2266                        return false;
2267                    }
2268                }
2269                true
2270            }
2271            (None, None) => true,
2272            _ => false,
2273        }
2274    }
2275
2276    #[test]
2277    fn test_hash_value_0() {
2278        let hash_set: std::collections::HashSet<Value> = [
2279            Value::Int(None),
2280            Value::Int(None),
2281            Value::BigInt(None),
2282            Value::BigInt(None),
2283            Value::Float(None),
2284            Value::Float(None),                // Null is not NaN
2285            Value::Float(Some(std::f32::NAN)), // NaN considered equal
2286            Value::Float(Some(std::f32::NAN)),
2287            Value::Double(None),
2288            Value::Double(None),
2289            Value::Double(Some(std::f64::NAN)),
2290            Value::Double(Some(std::f64::NAN)),
2291        ]
2292        .into_iter()
2293        .collect();
2294
2295        let unique: std::collections::HashSet<Value> = [
2296            Value::Int(None),
2297            Value::BigInt(None),
2298            Value::Float(None),
2299            Value::Double(None),
2300            Value::Float(Some(std::f32::NAN)),
2301            Value::Double(Some(std::f64::NAN)),
2302        ]
2303        .into_iter()
2304        .collect();
2305
2306        assert_eq!(hash_set, unique);
2307    }
2308
2309    #[test]
2310    fn test_hash_value_1() {
2311        let hash_set: std::collections::HashSet<Value> = [
2312            Value::Int(None),
2313            Value::Int(Some(1)),
2314            Value::Int(Some(1)),
2315            Value::BigInt(Some(2)),
2316            Value::BigInt(Some(2)),
2317            Value::Float(Some(3.0)),
2318            Value::Float(Some(3.0)),
2319            Value::Double(Some(3.0)),
2320            Value::Double(Some(3.0)),
2321            Value::BigInt(Some(5)),
2322        ]
2323        .into_iter()
2324        .collect();
2325
2326        let unique: std::collections::HashSet<Value> = [
2327            Value::BigInt(Some(5)),
2328            Value::Double(Some(3.0)),
2329            Value::Float(Some(3.0)),
2330            Value::BigInt(Some(2)),
2331            Value::Int(Some(1)),
2332            Value::Int(None),
2333        ]
2334        .into_iter()
2335        .collect();
2336
2337        assert_eq!(hash_set, unique);
2338    }
2339
2340    #[cfg(feature = "postgres-array")]
2341    #[test]
2342    fn test_hash_value_array() {
2343        assert_eq!(
2344            Into::<Value>::into(vec![0i32, 1, 2]),
2345            Value::Array(
2346                ArrayType::Int,
2347                Some(Box::new(vec![
2348                    Value::Int(Some(0)),
2349                    Value::Int(Some(1)),
2350                    Value::Int(Some(2))
2351                ]))
2352            )
2353        );
2354
2355        assert_eq!(
2356            Into::<Value>::into(vec![0f32, 1.0, 2.0]),
2357            Value::Array(
2358                ArrayType::Float,
2359                Some(Box::new(vec![
2360                    Value::Float(Some(0f32)),
2361                    Value::Float(Some(1.0)),
2362                    Value::Float(Some(2.0))
2363                ]))
2364            )
2365        );
2366
2367        let hash_set: std::collections::HashSet<Value> = [
2368            Into::<Value>::into(vec![0i32, 1, 2]),
2369            Into::<Value>::into(vec![0i32, 1, 2]),
2370            Into::<Value>::into(vec![0f32, 1.0, 2.0]),
2371            Into::<Value>::into(vec![0f32, 1.0, 2.0]),
2372            Into::<Value>::into(vec![3f32, 2.0, 1.0]),
2373        ]
2374        .into_iter()
2375        .collect();
2376
2377        let unique: std::collections::HashSet<Value> = [
2378            Into::<Value>::into(vec![0i32, 1, 2]),
2379            Into::<Value>::into(vec![0f32, 1.0, 2.0]),
2380            Into::<Value>::into(vec![3f32, 2.0, 1.0]),
2381        ]
2382        .into_iter()
2383        .collect();
2384
2385        assert_eq!(hash_set, unique);
2386    }
2387}