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