sea_query/
value.rs

1//! Container for all SQL value types.
2
3use std::borrow::Cow;
4
5use crate::{ColumnType, CommonSqlQueryBuilder, QueryBuilder, StringLen};
6
7#[cfg(test)]
8mod tests;
9
10pub mod prelude;
11#[allow(unused_imports)]
12use prelude::*;
13
14#[cfg(feature = "hashable-value")]
15mod hashable_value;
16
17mod value_class;
18pub use value_class::*;
19
20mod value_tuple;
21pub use value_tuple::*;
22
23#[cfg(feature = "with-json")]
24#[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
25mod with_json;
26
27#[cfg(feature = "with-json")]
28#[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
29pub use with_json::sea_value_to_json_value;
30
31#[cfg(feature = "with-chrono")]
32#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
33mod with_chrono;
34
35#[cfg(feature = "with-time")]
36#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
37pub mod time_format;
38
39#[cfg(feature = "with-time")]
40#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
41mod with_time;
42
43#[cfg(feature = "with-jiff")]
44#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
45pub(crate) mod with_jiff;
46
47#[cfg(feature = "with-rust_decimal")]
48#[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
49mod with_rust_decimal;
50
51#[cfg(feature = "with-bigdecimal")]
52#[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
53mod with_bigdecimal;
54
55#[cfg(feature = "with-uuid")]
56#[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
57mod with_uuid;
58
59#[cfg(feature = "with-ipnetwork")]
60#[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
61mod with_ipnetwork;
62
63#[cfg(feature = "with-mac_address")]
64#[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
65mod with_mac_address;
66
67#[cfg(feature = "postgres-array")]
68#[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
69pub mod with_array;
70
71#[cfg(feature = "postgres-vector")]
72#[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
73mod with_pgvector;
74
75#[cfg(all(test, feature = "serde", feature = "with-json"))]
76mod serde_tests;
77
78/// [`Value`] types variant for Postgres array
79#[derive(Clone, Debug, Eq, PartialEq, Hash)]
80#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
81pub enum ArrayType {
82    Bool,
83    TinyInt,
84    SmallInt,
85    Int,
86    BigInt,
87    TinyUnsigned,
88    SmallUnsigned,
89    Unsigned,
90    BigUnsigned,
91    Float,
92    Double,
93    String,
94    Char,
95    Bytes,
96
97    #[cfg(feature = "with-json")]
98    #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
99    Json,
100
101    #[cfg(feature = "with-chrono")]
102    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
103    ChronoDate,
104
105    #[cfg(feature = "with-chrono")]
106    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
107    ChronoTime,
108
109    #[cfg(feature = "with-chrono")]
110    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
111    ChronoDateTime,
112
113    #[cfg(feature = "with-chrono")]
114    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
115    ChronoDateTimeUtc,
116
117    #[cfg(feature = "with-chrono")]
118    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
119    ChronoDateTimeLocal,
120
121    #[cfg(feature = "with-chrono")]
122    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
123    ChronoDateTimeWithTimeZone,
124
125    #[cfg(feature = "with-time")]
126    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
127    TimeDate,
128
129    #[cfg(feature = "with-time")]
130    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
131    TimeTime,
132
133    #[cfg(feature = "with-time")]
134    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
135    TimeDateTime,
136
137    #[cfg(feature = "with-time")]
138    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
139    TimeDateTimeWithTimeZone,
140
141    #[cfg(feature = "with-jiff")]
142    #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
143    JiffDate,
144
145    #[cfg(feature = "with-jiff")]
146    #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
147    JiffTime,
148
149    #[cfg(feature = "with-jiff")]
150    #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
151    JiffDateTime,
152
153    #[cfg(feature = "with-jiff")]
154    #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
155    JiffTimestamp,
156
157    #[cfg(feature = "with-jiff")]
158    #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
159    JiffZoned,
160
161    #[cfg(feature = "with-uuid")]
162    #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
163    Uuid,
164
165    #[cfg(feature = "with-rust_decimal")]
166    #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
167    Decimal,
168
169    #[cfg(feature = "with-bigdecimal")]
170    #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
171    BigDecimal,
172
173    #[cfg(feature = "with-ipnetwork")]
174    #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
175    IpNetwork,
176
177    #[cfg(feature = "with-mac_address")]
178    #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
179    MacAddress,
180}
181
182/// Value variants
183///
184/// We want the inner Value to be exactly 1 pointer sized, so anything larger should be boxed.
185///
186/// If the `hashable-value` feature is enabled, NaN == NaN, which contradicts Rust's built-in
187/// implementation of NaN != NaN.
188#[derive(Clone, Debug)]
189#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
190#[cfg_attr(not(feature = "hashable-value"), derive(PartialEq))]
191pub enum Value {
192    Bool(Option<bool>),
193    TinyInt(Option<i8>),
194    SmallInt(Option<i16>),
195    Int(Option<i32>),
196    BigInt(Option<i64>),
197    TinyUnsigned(Option<u8>),
198    SmallUnsigned(Option<u16>),
199    Unsigned(Option<u32>),
200    BigUnsigned(Option<u64>),
201    Float(Option<f32>),
202    Double(Option<f64>),
203    String(Option<String>),
204    Char(Option<char>),
205
206    #[allow(clippy::box_collection)]
207    Bytes(Option<Vec<u8>>),
208
209    #[cfg(feature = "with-json")]
210    #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
211    Json(Option<Box<Json>>),
212
213    #[cfg(feature = "with-chrono")]
214    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
215    ChronoDate(Option<NaiveDate>),
216
217    #[cfg(feature = "with-chrono")]
218    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
219    ChronoTime(Option<NaiveTime>),
220
221    #[cfg(feature = "with-chrono")]
222    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
223    ChronoDateTime(Option<NaiveDateTime>),
224
225    #[cfg(feature = "with-chrono")]
226    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
227    ChronoDateTimeUtc(Option<DateTime<Utc>>),
228
229    #[cfg(feature = "with-chrono")]
230    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
231    ChronoDateTimeLocal(Option<DateTime<Local>>),
232
233    #[cfg(feature = "with-chrono")]
234    #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
235    ChronoDateTimeWithTimeZone(Option<DateTime<FixedOffset>>),
236
237    #[cfg(feature = "with-time")]
238    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
239    TimeDate(Option<time::Date>),
240
241    #[cfg(feature = "with-time")]
242    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
243    TimeTime(Option<time::Time>),
244
245    #[cfg(feature = "with-time")]
246    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
247    TimeDateTime(Option<PrimitiveDateTime>),
248
249    #[cfg(feature = "with-time")]
250    #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
251    TimeDateTimeWithTimeZone(Option<OffsetDateTime>),
252
253    #[cfg(feature = "with-jiff")]
254    #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
255    JiffDate(Option<jiff::civil::Date>),
256
257    #[cfg(feature = "with-jiff")]
258    #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
259    JiffTime(Option<jiff::civil::Time>),
260
261    #[cfg(feature = "with-jiff")]
262    #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
263    JiffDateTime(Option<Box<jiff::civil::DateTime>>),
264
265    #[cfg(feature = "with-jiff")]
266    #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
267    JiffTimestamp(Option<Box<Timestamp>>),
268
269    #[cfg(feature = "with-jiff")]
270    #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
271    JiffZoned(Option<Box<Zoned>>),
272
273    #[cfg(feature = "with-uuid")]
274    #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
275    Uuid(Option<Uuid>),
276
277    #[cfg(feature = "with-rust_decimal")]
278    #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
279    Decimal(Option<Decimal>),
280
281    #[cfg(feature = "with-bigdecimal")]
282    #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
283    BigDecimal(Option<Box<BigDecimal>>),
284
285    #[cfg(feature = "postgres-array")]
286    #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
287    Array(ArrayType, Option<Box<Vec<Value>>>),
288
289    #[cfg(feature = "postgres-vector")]
290    #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
291    Vector(Option<pgvector::Vector>),
292
293    #[cfg(feature = "with-ipnetwork")]
294    #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
295    IpNetwork(Option<IpNetwork>),
296
297    #[cfg(feature = "with-mac_address")]
298    #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
299    MacAddress(Option<MacAddress>),
300
301    #[cfg(feature = "postgres-range")]
302    #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
303    Range(Option<Box<RangeType>>),
304}
305
306/// This test is to check if the size of [`Value`] exceeds the limit.
307///
308/// If the size exceeds the limit, you should box the variant.
309/// Previously, the size was 24. We bumped it to 32 such that `String`
310/// can be unboxed.
311///
312/// When the `with-json` feature is enabled, the size of `Value` may
313/// exceed 32 bytes to 72 bytes if serde_json feature `preserve_order`
314/// is enabled as different Map implementation can be used.
315pub const VALUE_SIZE: usize = check_value_size();
316const MAX_VALUE_SIZE: usize = 32;
317
318const fn check_value_size() -> usize {
319    if std::mem::size_of::<Value>() > MAX_VALUE_SIZE {
320        panic!(
321            "the size of Value shouldn't be greater than the expected MAX_VALUE_SIZE (32 bytes by default)"
322        )
323    }
324    std::mem::size_of::<Value>()
325}
326
327impl Value {
328    pub fn unwrap<T>(self) -> T
329    where
330        T: ValueType,
331    {
332        T::unwrap(self)
333    }
334
335    pub fn expect<T>(self, msg: &str) -> T
336    where
337        T: ValueType,
338    {
339        T::expect(self, msg)
340    }
341
342    /// Get the null variant of self
343    ///
344    /// ```
345    /// use sea_query::Value;
346    ///
347    /// let v = Value::Int(Some(2));
348    /// let n = v.as_null();
349    ///
350    /// assert_eq!(n, Value::Int(None));
351    ///
352    /// // one liner:
353    /// assert_eq!(Into::<Value>::into(2.2).as_null(), Value::Double(None));
354    /// ```
355    pub fn as_null(&self) -> Self {
356        match self {
357            Self::Bool(_) => Self::Bool(None),
358            Self::TinyInt(_) => Self::TinyInt(None),
359            Self::SmallInt(_) => Self::SmallInt(None),
360            Self::Int(_) => Self::Int(None),
361            Self::BigInt(_) => Self::BigInt(None),
362            Self::TinyUnsigned(_) => Self::TinyUnsigned(None),
363            Self::SmallUnsigned(_) => Self::SmallUnsigned(None),
364            Self::Unsigned(_) => Self::Unsigned(None),
365            Self::BigUnsigned(_) => Self::BigUnsigned(None),
366            Self::Float(_) => Self::Float(None),
367            Self::Double(_) => Self::Double(None),
368            Self::String(_) => Self::String(None),
369            Self::Char(_) => Self::Char(None),
370            Self::Bytes(_) => Self::Bytes(None),
371
372            #[cfg(feature = "with-json")]
373            #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
374            Self::Json(_) => Self::Json(None),
375
376            #[cfg(feature = "with-chrono")]
377            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
378            Self::ChronoDate(_) => Self::ChronoDate(None),
379
380            #[cfg(feature = "with-chrono")]
381            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
382            Self::ChronoTime(_) => Self::ChronoTime(None),
383
384            #[cfg(feature = "with-chrono")]
385            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
386            Self::ChronoDateTime(_) => Self::ChronoDateTime(None),
387
388            #[cfg(feature = "with-chrono")]
389            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
390            Self::ChronoDateTimeUtc(_) => Self::ChronoDateTimeUtc(None),
391
392            #[cfg(feature = "with-chrono")]
393            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
394            Self::ChronoDateTimeLocal(_) => Self::ChronoDateTimeLocal(None),
395
396            #[cfg(feature = "with-chrono")]
397            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
398            Self::ChronoDateTimeWithTimeZone(_) => Self::ChronoDateTimeWithTimeZone(None),
399
400            #[cfg(feature = "with-time")]
401            #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
402            Self::TimeDate(_) => Self::TimeDate(None),
403
404            #[cfg(feature = "with-time")]
405            #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
406            Self::TimeTime(_) => Self::TimeTime(None),
407
408            #[cfg(feature = "with-time")]
409            #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
410            Self::TimeDateTime(_) => Self::TimeDateTime(None),
411
412            #[cfg(feature = "with-time")]
413            #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
414            Self::TimeDateTimeWithTimeZone(_) => Self::TimeDateTimeWithTimeZone(None),
415
416            #[cfg(feature = "with-jiff")]
417            #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
418            Self::JiffDate(_) => Self::JiffDate(None),
419
420            #[cfg(feature = "with-jiff")]
421            #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
422            Self::JiffTime(_) => Self::JiffTime(None),
423
424            #[cfg(feature = "with-jiff")]
425            #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
426            Self::JiffDateTime(_) => Self::JiffDateTime(None),
427
428            #[cfg(feature = "with-jiff")]
429            #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
430            Self::JiffTimestamp(_) => Self::JiffTimestamp(None),
431
432            #[cfg(feature = "with-jiff")]
433            #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
434            Self::JiffZoned(_) => Self::JiffZoned(None),
435
436            #[cfg(feature = "with-uuid")]
437            #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
438            Self::Uuid(_) => Self::Uuid(None),
439
440            #[cfg(feature = "with-rust_decimal")]
441            #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
442            Self::Decimal(_) => Self::Decimal(None),
443
444            #[cfg(feature = "with-bigdecimal")]
445            #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
446            Self::BigDecimal(_) => Self::BigDecimal(None),
447
448            #[cfg(feature = "postgres-array")]
449            #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
450            Self::Array(ty, _) => Self::Array(ty.clone(), None),
451
452            #[cfg(feature = "postgres-vector")]
453            #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
454            Self::Vector(_) => Self::Vector(None),
455
456            #[cfg(feature = "with-ipnetwork")]
457            #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
458            Self::IpNetwork(_) => Self::IpNetwork(None),
459
460            #[cfg(feature = "with-mac_address")]
461            #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
462            Self::MacAddress(_) => Self::MacAddress(None),
463
464            #[cfg(feature = "postgres-range")]
465            #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
466            Self::Range(_) => Self::Range(None),
467        }
468    }
469
470    /// Get a default value of self's type
471    ///
472    /// ```
473    /// use sea_query::Value;
474    ///
475    /// let v = Value::Int(None);
476    /// let n = v.dummy_value();
477    /// assert_eq!(n, Value::Int(Some(0)));
478    /// ```
479    pub fn dummy_value(&self) -> Self {
480        match self {
481            Self::Bool(_) => Self::Bool(Some(Default::default())),
482            Self::TinyInt(_) => Self::TinyInt(Some(Default::default())),
483            Self::SmallInt(_) => Self::SmallInt(Some(Default::default())),
484            Self::Int(_) => Self::Int(Some(Default::default())),
485            Self::BigInt(_) => Self::BigInt(Some(Default::default())),
486            Self::TinyUnsigned(_) => Self::TinyUnsigned(Some(Default::default())),
487            Self::SmallUnsigned(_) => Self::SmallUnsigned(Some(Default::default())),
488            Self::Unsigned(_) => Self::Unsigned(Some(Default::default())),
489            Self::BigUnsigned(_) => Self::BigUnsigned(Some(Default::default())),
490            Self::Float(_) => Self::Float(Some(Default::default())),
491            Self::Double(_) => Self::Double(Some(Default::default())),
492            Self::String(_) => Self::String(Some(Default::default())),
493            Self::Char(_) => Self::Char(Some(Default::default())),
494            Self::Bytes(_) => Self::Bytes(Some(Default::default())),
495
496            #[cfg(feature = "with-json")]
497            #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
498            Self::Json(_) => Self::Json(Some(Default::default())),
499
500            #[cfg(feature = "with-chrono")]
501            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
502            Self::ChronoDate(_) => Self::ChronoDate(Some(Default::default())),
503
504            #[cfg(feature = "with-chrono")]
505            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
506            Self::ChronoTime(_) => Self::ChronoTime(Some(Default::default())),
507
508            #[cfg(feature = "with-chrono")]
509            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
510            Self::ChronoDateTime(_) => Self::ChronoDateTime(Some(Default::default())),
511
512            #[cfg(feature = "with-chrono")]
513            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
514            Self::ChronoDateTimeUtc(_) => Self::ChronoDateTimeUtc(Some(Default::default())),
515
516            #[cfg(feature = "with-chrono")]
517            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
518            Self::ChronoDateTimeLocal(_) => Self::ChronoDateTimeLocal(Some(Default::default())),
519
520            #[cfg(feature = "with-chrono")]
521            #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
522            Self::ChronoDateTimeWithTimeZone(_) => {
523                Self::ChronoDateTimeWithTimeZone(Some(Default::default()))
524            }
525
526            #[cfg(feature = "with-time")]
527            #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
528            Self::TimeDate(_) => Self::TimeDate(Some(time::Date::MIN)),
529
530            #[cfg(feature = "with-time")]
531            #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
532            Self::TimeTime(_) => Self::TimeTime(Some(time::Time::MIDNIGHT)),
533
534            #[cfg(feature = "with-time")]
535            #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
536            Self::TimeDateTime(_) => Self::TimeDateTime(Some(PrimitiveDateTime::MIN)),
537
538            #[cfg(feature = "with-time")]
539            #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
540            Self::TimeDateTimeWithTimeZone(_) => {
541                Self::TimeDateTimeWithTimeZone(Some(OffsetDateTime::UNIX_EPOCH))
542            }
543
544            #[cfg(feature = "with-jiff")]
545            #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
546            Self::JiffDate(_) => Self::JiffDate(Some(jiff::civil::date(1970, 1, 1))),
547
548            #[cfg(feature = "with-jiff")]
549            #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
550            Self::JiffTime(_) => Self::JiffTime(Some(jiff::civil::time(0, 0, 0, 0))),
551
552            #[cfg(feature = "with-jiff")]
553            #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
554            Self::JiffDateTime(_) => {
555                Self::JiffDateTime(Some(jiff::civil::date(1970, 1, 1).at(0, 0, 0, 0).into()))
556            }
557
558            #[cfg(feature = "with-jiff")]
559            #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
560            Self::JiffTimestamp(_) => Self::JiffTimestamp(Some(Timestamp::UNIX_EPOCH.into())),
561
562            #[cfg(feature = "with-jiff")]
563            #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
564            Self::JiffZoned(_) => Self::JiffZoned(Some(
565                Timestamp::UNIX_EPOCH
566                    .to_zoned(jiff::tz::TimeZone::UTC)
567                    .into(),
568            )),
569
570            #[cfg(feature = "with-uuid")]
571            #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
572            Self::Uuid(_) => Self::Uuid(Some(Default::default())),
573
574            #[cfg(feature = "with-rust_decimal")]
575            #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
576            Self::Decimal(_) => Self::Decimal(Some(Default::default())),
577
578            #[cfg(feature = "with-bigdecimal")]
579            #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
580            Self::BigDecimal(_) => Self::BigDecimal(Some(Default::default())),
581
582            #[cfg(feature = "postgres-array")]
583            #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
584            Self::Array(ty, _) => Self::Array(ty.clone(), Some(Default::default())),
585
586            #[cfg(feature = "postgres-vector")]
587            #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
588            Self::Vector(_) => Self::Vector(Some(vec![].into())),
589
590            #[cfg(feature = "with-ipnetwork")]
591            #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
592            Self::IpNetwork(_) => Self::IpNetwork(Some("0.0.0.0".parse().unwrap())),
593
594            #[cfg(feature = "with-mac_address")]
595            #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
596            Self::MacAddress(_) => Self::MacAddress(Some(Default::default())),
597
598            #[cfg(feature = "postgres-range")]
599            #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
600            Self::Range(_) => Self::Range(Some(Default::default())),
601        }
602    }
603}
604
605impl From<&[u8]> for Value {
606    fn from(x: &[u8]) -> Value {
607        Value::Bytes(Some(x.into()))
608    }
609}
610
611impl From<&str> for Value {
612    fn from(x: &str) -> Value {
613        Value::String(Some(x.to_owned()))
614    }
615}
616
617impl From<&String> for Value {
618    fn from(x: &String) -> Value {
619        Value::String(Some(x.clone()))
620    }
621}
622
623impl<T> From<Option<T>> for Value
624where
625    T: Into<Value> + Nullable,
626{
627    fn from(x: Option<T>) -> Value {
628        match x {
629            Some(v) => v.into(),
630            None => T::null(),
631        }
632    }
633}
634
635impl From<Cow<'_, str>> for Value {
636    fn from(x: Cow<'_, str>) -> Value {
637        x.into_owned().into()
638    }
639}
640
641impl IntoIterator for Values {
642    type Item = Value;
643    type IntoIter = std::vec::IntoIter<Self::Item>;
644
645    fn into_iter(self) -> Self::IntoIter {
646        self.0.into_iter()
647    }
648}
649
650impl std::fmt::Display for Value {
651    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
652        CommonSqlQueryBuilder.write_value(f, self)
653    }
654}
655
656pub trait ValueType: Sized {
657    fn try_from(v: Value) -> Result<Self, ValueTypeErr>;
658
659    fn unwrap(v: Value) -> Self {
660        Self::try_from(v).unwrap()
661    }
662
663    fn expect(v: Value, msg: &str) -> Self {
664        Self::try_from(v).expect(msg)
665    }
666
667    fn is_option() -> bool {
668        false
669    }
670
671    fn type_name() -> String;
672
673    fn array_type() -> ArrayType;
674
675    fn column_type() -> ColumnType;
676
677    fn enum_type_name() -> Option<&'static str> {
678        None
679    }
680}
681
682impl<T> ValueType for Option<T>
683where
684    T: ValueType + Nullable,
685{
686    fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
687        if v == T::null() {
688            Ok(None)
689        } else {
690            Ok(Some(T::try_from(v)?))
691        }
692    }
693
694    fn is_option() -> bool {
695        true
696    }
697
698    fn type_name() -> String {
699        format!("Option<{}>", T::type_name())
700    }
701
702    fn array_type() -> ArrayType {
703        T::array_type()
704    }
705
706    fn column_type() -> ColumnType {
707        T::column_type()
708    }
709}
710
711impl ValueType for Cow<'_, str> {
712    fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
713        match v {
714            Value::String(Some(x)) => Ok((x).into()),
715            _ => Err(ValueTypeErr),
716        }
717    }
718
719    fn type_name() -> String {
720        "Cow<str>".into()
721    }
722
723    fn array_type() -> ArrayType {
724        ArrayType::String
725    }
726
727    fn column_type() -> ColumnType {
728        ColumnType::String(StringLen::None)
729    }
730}
731
732#[derive(Debug)]
733pub struct ValueTypeErr;
734
735impl std::error::Error for ValueTypeErr {}
736
737impl std::fmt::Display for ValueTypeErr {
738    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
739        f.write_str("Value type mismatch")
740    }
741}
742
743#[derive(Clone, Debug, PartialEq)]
744pub struct Values(pub Vec<Value>);
745
746impl Values {
747    pub fn iter(&self) -> impl Iterator<Item = &Value> {
748        self.0.iter()
749    }
750}
751
752pub trait Nullable {
753    fn null() -> Value;
754}
755
756impl Nullable for &str {
757    fn null() -> Value {
758        Value::String(None)
759    }
760}
761
762macro_rules! type_to_value {
763    ( $type: ty, $name: ident, $col_type: expr ) => {
764        impl From<$type> for Value {
765            fn from(x: $type) -> Value {
766                Value::$name(Some(x))
767            }
768        }
769
770        impl Nullable for $type {
771            fn null() -> Value {
772                Value::$name(None)
773            }
774        }
775
776        impl ValueType for $type {
777            fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
778                match v {
779                    Value::$name(Some(x)) => Ok(x),
780                    _ => Err(ValueTypeErr),
781                }
782            }
783
784            fn type_name() -> String {
785                stringify!($type).to_owned()
786            }
787
788            fn array_type() -> ArrayType {
789                ArrayType::$name
790            }
791
792            fn column_type() -> ColumnType {
793                use ColumnType::*;
794                $col_type
795            }
796        }
797    };
798}
799use type_to_value;
800
801type_to_value!(bool, Bool, Boolean);
802type_to_value!(i8, TinyInt, TinyInteger);
803type_to_value!(i16, SmallInt, SmallInteger);
804type_to_value!(i32, Int, Integer);
805type_to_value!(i64, BigInt, BigInteger);
806type_to_value!(u8, TinyUnsigned, TinyUnsigned);
807type_to_value!(u16, SmallUnsigned, SmallUnsigned);
808type_to_value!(u32, Unsigned, Unsigned);
809type_to_value!(u64, BigUnsigned, BigUnsigned);
810type_to_value!(f32, Float, Float);
811type_to_value!(f64, Double, Double);
812type_to_value!(char, Char, Char(None));
813type_to_value!(Vec<u8>, Bytes, VarBinary(StringLen::None));
814type_to_value!(String, String, String(StringLen::None));
815
816#[allow(unused_macros)]
817macro_rules! type_to_box_value {
818    ( $type: ty, $name: ident, $col_type: expr ) => {
819        impl From<$type> for Value {
820            fn from(x: $type) -> Value {
821                Value::$name(Some(Box::new(x)))
822            }
823        }
824
825        impl Nullable for $type {
826            fn null() -> Value {
827                Value::$name(None)
828            }
829        }
830
831        impl ValueType for $type {
832            fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
833                match v {
834                    Value::$name(Some(x)) => Ok(*x),
835                    _ => Err(ValueTypeErr),
836                }
837            }
838
839            fn type_name() -> String {
840                stringify!($type).to_owned()
841            }
842
843            fn array_type() -> ArrayType {
844                ArrayType::$name
845            }
846
847            fn column_type() -> ColumnType {
848                use ColumnType::*;
849                $col_type
850            }
851        }
852    };
853}
854
855#[allow(unused_imports)]
856use type_to_box_value;