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