1use std::borrow::Cow;
4
5use crate::{ColumnType, CommonSqlQueryBuilder, QueryBuilder, RcOrArc, 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 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 postgres_array;
70
71#[cfg(feature = "postgres-vector")]
72#[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
73mod postgres_vector;
74
75#[cfg(feature = "postgres-range")]
76#[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
77mod postgres_range;
78
79#[cfg(all(test, feature = "serde", feature = "with-json"))]
80mod serde_tests;
81
82#[derive(Clone, Debug, Eq, PartialEq, Hash)]
84#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
85pub enum ArrayType {
86 Bool,
87 TinyInt,
88 SmallInt,
89 Int,
90 BigInt,
91 TinyUnsigned,
92 SmallUnsigned,
93 Unsigned,
94 BigUnsigned,
95 Float,
96 Double,
97 String,
98 #[cfg(feature = "backend-postgres")]
100 #[cfg_attr(docsrs, doc(cfg(feature = "backend-postgres")))]
101 Enum(Box<EnumTypeName>),
102 Char,
103 Bytes,
104
105 #[cfg(feature = "with-json")]
106 #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
107 Json,
108
109 #[cfg(feature = "with-chrono")]
110 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
111 ChronoDate,
112
113 #[cfg(feature = "with-chrono")]
114 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
115 ChronoTime,
116
117 #[cfg(feature = "with-chrono")]
118 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
119 ChronoDateTime,
120
121 #[cfg(feature = "with-chrono")]
122 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
123 ChronoDateTimeUtc,
124
125 #[cfg(feature = "with-chrono")]
126 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
127 ChronoDateTimeLocal,
128
129 #[cfg(feature = "with-chrono")]
130 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
131 ChronoDateTimeWithTimeZone,
132
133 #[cfg(feature = "with-time")]
134 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
135 TimeDate,
136
137 #[cfg(feature = "with-time")]
138 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
139 TimeTime,
140
141 #[cfg(feature = "with-time")]
142 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
143 TimeDateTime,
144
145 #[cfg(feature = "with-time")]
146 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
147 TimeDateTimeWithTimeZone,
148
149 #[cfg(feature = "with-jiff")]
150 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
151 JiffDate,
152
153 #[cfg(feature = "with-jiff")]
154 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
155 JiffTime,
156
157 #[cfg(feature = "with-jiff")]
158 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
159 JiffDateTime,
160
161 #[cfg(feature = "with-jiff")]
162 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
163 JiffTimestamp,
164
165 #[cfg(feature = "with-uuid")]
166 #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
167 Uuid,
168
169 #[cfg(feature = "with-rust_decimal")]
170 #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
171 Decimal,
172
173 #[cfg(feature = "with-bigdecimal")]
174 #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
175 BigDecimal,
176
177 #[cfg(feature = "with-ipnetwork")]
178 #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
179 IpNetwork,
180
181 #[cfg(feature = "with-mac_address")]
182 #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
183 MacAddress,
184
185 #[cfg(feature = "postgres-range")]
186 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
187 Range,
188}
189
190pub type EnumTypeName = RcOrArc<str>;
192
193#[derive(Clone, Debug, Eq, PartialEq, Hash)]
194#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
195pub struct Enum {
196 pub type_name: EnumTypeName,
197 pub value: Cow<'static, str>,
198}
199
200#[derive(Debug, Clone, PartialEq, Eq, Hash)]
203#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
204pub enum OptionEnum {
205 Some(Box<Enum>),
206 None(EnumTypeName),
207}
208
209impl OptionEnum {
210 pub fn is_some(&self) -> bool {
228 matches!(*self, OptionEnum::Some(_))
229 }
230}
231
232#[derive(Clone, Debug)]
239#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
240#[cfg_attr(not(feature = "hashable-value"), derive(PartialEq))]
241pub enum Value {
242 Bool(Option<bool>),
243 TinyInt(Option<i8>),
244 SmallInt(Option<i16>),
245 Int(Option<i32>),
246 BigInt(Option<i64>),
247 TinyUnsigned(Option<u8>),
248 SmallUnsigned(Option<u16>),
249 Unsigned(Option<u32>),
250 BigUnsigned(Option<u64>),
251 Float(Option<f32>),
252 Double(Option<f64>),
253 String(Option<String>),
254 Enum(OptionEnum),
255 Char(Option<char>),
256
257 #[allow(clippy::box_collection)]
258 Bytes(Option<Vec<u8>>),
259
260 #[cfg(feature = "with-json")]
261 #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
262 Json(Option<Box<Json>>),
263
264 #[cfg(feature = "with-chrono")]
265 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
266 ChronoDate(Option<NaiveDate>),
267
268 #[cfg(feature = "with-chrono")]
269 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
270 ChronoTime(Option<NaiveTime>),
271
272 #[cfg(feature = "with-chrono")]
273 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
274 ChronoDateTime(Option<NaiveDateTime>),
275
276 #[cfg(feature = "with-chrono")]
277 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
278 ChronoDateTimeUtc(Option<DateTime<Utc>>),
279
280 #[cfg(feature = "with-chrono")]
281 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
282 ChronoDateTimeLocal(Option<DateTime<Local>>),
283
284 #[cfg(feature = "with-chrono")]
285 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
286 ChronoDateTimeWithTimeZone(Option<DateTime<FixedOffset>>),
287
288 #[cfg(feature = "with-time")]
289 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
290 TimeDate(Option<time::Date>),
291
292 #[cfg(feature = "with-time")]
293 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
294 TimeTime(Option<time::Time>),
295
296 #[cfg(feature = "with-time")]
297 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
298 TimeDateTime(Option<PrimitiveDateTime>),
299
300 #[cfg(feature = "with-time")]
301 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
302 TimeDateTimeWithTimeZone(Option<OffsetDateTime>),
303
304 #[cfg(feature = "with-jiff")]
305 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
306 JiffDate(Option<jiff::civil::Date>),
307
308 #[cfg(feature = "with-jiff")]
309 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
310 JiffTime(Option<jiff::civil::Time>),
311
312 #[cfg(feature = "with-jiff")]
313 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
314 JiffDateTime(Option<Box<jiff::civil::DateTime>>),
315
316 #[cfg(feature = "with-jiff")]
317 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
318 JiffTimestamp(Option<Box<Timestamp>>),
319
320 #[cfg(feature = "with-uuid")]
321 #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
322 Uuid(Option<Uuid>),
323
324 #[cfg(feature = "with-rust_decimal")]
325 #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
326 Decimal(Option<Decimal>),
327
328 #[cfg(feature = "with-bigdecimal")]
329 #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
330 BigDecimal(Option<Box<BigDecimal>>),
331
332 #[cfg(feature = "postgres-array")]
333 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
334 Array(ArrayType, Option<Box<Vec<Value>>>),
335
336 #[cfg(feature = "postgres-vector")]
337 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
338 Vector(Option<pgvector::Vector>),
339
340 #[cfg(feature = "with-ipnetwork")]
341 #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
342 IpNetwork(Option<IpNetwork>),
343
344 #[cfg(feature = "with-mac_address")]
345 #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
346 MacAddress(Option<MacAddress>),
347
348 #[cfg(feature = "postgres-range")]
349 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
350 Range(Option<Box<RangeType>>),
351}
352
353pub const VALUE_SIZE: usize = check_value_size();
363const MAX_VALUE_SIZE: usize = 32;
364
365const fn check_value_size() -> usize {
366 if std::mem::size_of::<Value>() > MAX_VALUE_SIZE {
367 panic!(
368 "the size of Value shouldn't be greater than the expected MAX_VALUE_SIZE (32 bytes by default)"
369 )
370 }
371 std::mem::size_of::<Value>()
372}
373
374impl Value {
375 pub fn unwrap<T>(self) -> T
376 where
377 T: ValueType,
378 {
379 T::unwrap(self)
380 }
381
382 pub fn expect<T>(self, msg: &str) -> T
383 where
384 T: ValueType,
385 {
386 T::expect(self, msg)
387 }
388
389 pub fn as_null(&self) -> Self {
403 match self {
404 Self::Bool(_) => Self::Bool(None),
405 Self::TinyInt(_) => Self::TinyInt(None),
406 Self::SmallInt(_) => Self::SmallInt(None),
407 Self::Int(_) => Self::Int(None),
408 Self::BigInt(_) => Self::BigInt(None),
409 Self::TinyUnsigned(_) => Self::TinyUnsigned(None),
410 Self::SmallUnsigned(_) => Self::SmallUnsigned(None),
411 Self::Unsigned(_) => Self::Unsigned(None),
412 Self::BigUnsigned(_) => Self::BigUnsigned(None),
413 Self::Float(_) => Self::Float(None),
414 Self::Double(_) => Self::Double(None),
415 Self::String(_) => Self::String(None),
416 Self::Enum(OptionEnum::Some(v)) => Self::Enum(OptionEnum::None(v.type_name.clone())),
417 Self::Enum(OptionEnum::None(type_name)) => {
418 Self::Enum(OptionEnum::None(type_name.clone()))
419 }
420 Self::Char(_) => Self::Char(None),
421 Self::Bytes(_) => Self::Bytes(None),
422
423 #[cfg(feature = "with-json")]
424 #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
425 Self::Json(_) => Self::Json(None),
426
427 #[cfg(feature = "with-chrono")]
428 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
429 Self::ChronoDate(_) => Self::ChronoDate(None),
430
431 #[cfg(feature = "with-chrono")]
432 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
433 Self::ChronoTime(_) => Self::ChronoTime(None),
434
435 #[cfg(feature = "with-chrono")]
436 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
437 Self::ChronoDateTime(_) => Self::ChronoDateTime(None),
438
439 #[cfg(feature = "with-chrono")]
440 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
441 Self::ChronoDateTimeUtc(_) => Self::ChronoDateTimeUtc(None),
442
443 #[cfg(feature = "with-chrono")]
444 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
445 Self::ChronoDateTimeLocal(_) => Self::ChronoDateTimeLocal(None),
446
447 #[cfg(feature = "with-chrono")]
448 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
449 Self::ChronoDateTimeWithTimeZone(_) => Self::ChronoDateTimeWithTimeZone(None),
450
451 #[cfg(feature = "with-time")]
452 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
453 Self::TimeDate(_) => Self::TimeDate(None),
454
455 #[cfg(feature = "with-time")]
456 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
457 Self::TimeTime(_) => Self::TimeTime(None),
458
459 #[cfg(feature = "with-time")]
460 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
461 Self::TimeDateTime(_) => Self::TimeDateTime(None),
462
463 #[cfg(feature = "with-time")]
464 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
465 Self::TimeDateTimeWithTimeZone(_) => Self::TimeDateTimeWithTimeZone(None),
466
467 #[cfg(feature = "with-jiff")]
468 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
469 Self::JiffDate(_) => Self::JiffDate(None),
470
471 #[cfg(feature = "with-jiff")]
472 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
473 Self::JiffTime(_) => Self::JiffTime(None),
474
475 #[cfg(feature = "with-jiff")]
476 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
477 Self::JiffDateTime(_) => Self::JiffDateTime(None),
478
479 #[cfg(feature = "with-jiff")]
480 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
481 Self::JiffTimestamp(_) => Self::JiffTimestamp(None),
482
483 #[cfg(feature = "with-uuid")]
484 #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
485 Self::Uuid(_) => Self::Uuid(None),
486
487 #[cfg(feature = "with-rust_decimal")]
488 #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
489 Self::Decimal(_) => Self::Decimal(None),
490
491 #[cfg(feature = "with-bigdecimal")]
492 #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
493 Self::BigDecimal(_) => Self::BigDecimal(None),
494
495 #[cfg(feature = "postgres-array")]
496 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
497 Self::Array(ty, _) => Self::Array(ty.clone(), None),
498
499 #[cfg(feature = "postgres-vector")]
500 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
501 Self::Vector(_) => Self::Vector(None),
502
503 #[cfg(feature = "with-ipnetwork")]
504 #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
505 Self::IpNetwork(_) => Self::IpNetwork(None),
506
507 #[cfg(feature = "with-mac_address")]
508 #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
509 Self::MacAddress(_) => Self::MacAddress(None),
510
511 #[cfg(feature = "postgres-range")]
512 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
513 Self::Range(_) => Self::Range(None),
514 }
515 }
516
517 pub fn is_some(&self) -> bool {
526 match self {
527 Self::Bool(v) => v.is_some(),
528 Self::TinyInt(v) => v.is_some(),
529 Self::SmallInt(v) => v.is_some(),
530 Self::Int(v) => v.is_some(),
531 Self::BigInt(v) => v.is_some(),
532 Self::TinyUnsigned(v) => v.is_some(),
533 Self::SmallUnsigned(v) => v.is_some(),
534 Self::Unsigned(v) => v.is_some(),
535 Self::BigUnsigned(v) => v.is_some(),
536 Self::Float(v) => v.is_some(),
537 Self::Double(v) => v.is_some(),
538 Self::String(v) => v.is_some(),
539 Self::Enum(v) => v.is_some(),
540 Self::Char(v) => v.is_some(),
541 Self::Bytes(v) => v.is_some(),
542
543 #[cfg(feature = "with-json")]
544 #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
545 Self::Json(v) => v.is_some(),
546
547 #[cfg(feature = "with-chrono")]
548 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
549 Self::ChronoDate(v) => v.is_some(),
550
551 #[cfg(feature = "with-chrono")]
552 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
553 Self::ChronoTime(v) => v.is_some(),
554
555 #[cfg(feature = "with-chrono")]
556 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
557 Self::ChronoDateTime(v) => v.is_some(),
558
559 #[cfg(feature = "with-chrono")]
560 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
561 Self::ChronoDateTimeUtc(v) => v.is_some(),
562
563 #[cfg(feature = "with-chrono")]
564 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
565 Self::ChronoDateTimeLocal(v) => v.is_some(),
566
567 #[cfg(feature = "with-chrono")]
568 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
569 Self::ChronoDateTimeWithTimeZone(v) => v.is_some(),
570
571 #[cfg(feature = "with-time")]
572 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
573 Self::TimeDate(v) => v.is_some(),
574
575 #[cfg(feature = "with-time")]
576 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
577 Self::TimeTime(v) => v.is_some(),
578
579 #[cfg(feature = "with-time")]
580 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
581 Self::TimeDateTime(v) => v.is_some(),
582
583 #[cfg(feature = "with-time")]
584 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
585 Self::TimeDateTimeWithTimeZone(v) => v.is_some(),
586
587 #[cfg(feature = "with-jiff")]
588 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
589 Self::JiffDate(v) => v.is_some(),
590
591 #[cfg(feature = "with-jiff")]
592 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
593 Self::JiffTime(v) => v.is_some(),
594
595 #[cfg(feature = "with-jiff")]
596 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
597 Self::JiffDateTime(v) => v.is_some(),
598
599 #[cfg(feature = "with-jiff")]
600 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
601 Self::JiffTimestamp(v) => v.is_some(),
602
603 #[cfg(feature = "with-uuid")]
604 #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
605 Self::Uuid(v) => v.is_some(),
606
607 #[cfg(feature = "with-rust_decimal")]
608 #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
609 Self::Decimal(v) => v.is_some(),
610
611 #[cfg(feature = "with-bigdecimal")]
612 #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
613 Self::BigDecimal(v) => v.is_some(),
614
615 #[cfg(feature = "postgres-array")]
616 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
617 Self::Array(_, v) => v.is_some(),
618
619 #[cfg(feature = "postgres-vector")]
620 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
621 Self::Vector(v) => v.is_some(),
622
623 #[cfg(feature = "with-ipnetwork")]
624 #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
625 Self::IpNetwork(v) => v.is_some(),
626
627 #[cfg(feature = "with-mac_address")]
628 #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
629 Self::MacAddress(v) => v.is_some(),
630
631 #[cfg(feature = "postgres-range")]
632 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
633 Self::Range(v) => v.is_some(),
634 }
635 }
636
637 pub fn dummy_value(&self) -> Self {
647 match self {
648 Self::Bool(_) => Self::Bool(Some(Default::default())),
649 Self::TinyInt(_) => Self::TinyInt(Some(Default::default())),
650 Self::SmallInt(_) => Self::SmallInt(Some(Default::default())),
651 Self::Int(_) => Self::Int(Some(Default::default())),
652 Self::BigInt(_) => Self::BigInt(Some(Default::default())),
653 Self::TinyUnsigned(_) => Self::TinyUnsigned(Some(Default::default())),
654 Self::SmallUnsigned(_) => Self::SmallUnsigned(Some(Default::default())),
655 Self::Unsigned(_) => Self::Unsigned(Some(Default::default())),
656 Self::BigUnsigned(_) => Self::BigUnsigned(Some(Default::default())),
657 Self::Float(_) => Self::Float(Some(Default::default())),
658 Self::Double(_) => Self::Double(Some(Default::default())),
659 Self::String(_) => Self::String(Some(Default::default())),
660 Self::Enum(v) => {
661 let type_name = match v {
662 OptionEnum::Some(v) => v.type_name.clone(),
663 OptionEnum::None(type_name) => type_name.clone(),
664 };
665 Self::Enum(OptionEnum::Some(Box::new(Enum {
666 type_name,
667 value: Cow::Borrowed(""),
668 })))
669 }
670 Self::Char(_) => Self::Char(Some(Default::default())),
671 Self::Bytes(_) => Self::Bytes(Some(Default::default())),
672
673 #[cfg(feature = "with-json")]
674 #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
675 Self::Json(_) => Self::Json(Some(Default::default())),
676
677 #[cfg(feature = "with-chrono")]
678 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
679 Self::ChronoDate(_) => Self::ChronoDate(Some(Default::default())),
680
681 #[cfg(feature = "with-chrono")]
682 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
683 Self::ChronoTime(_) => Self::ChronoTime(Some(Default::default())),
684
685 #[cfg(feature = "with-chrono")]
686 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
687 Self::ChronoDateTime(_) => Self::ChronoDateTime(Some(Default::default())),
688
689 #[cfg(feature = "with-chrono")]
690 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
691 Self::ChronoDateTimeUtc(_) => Self::ChronoDateTimeUtc(Some(Default::default())),
692
693 #[cfg(feature = "with-chrono")]
694 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
695 Self::ChronoDateTimeLocal(_) => Self::ChronoDateTimeLocal(Some(Default::default())),
696
697 #[cfg(feature = "with-chrono")]
698 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
699 Self::ChronoDateTimeWithTimeZone(_) => {
700 Self::ChronoDateTimeWithTimeZone(Some(Default::default()))
701 }
702
703 #[cfg(feature = "with-time")]
704 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
705 Self::TimeDate(_) => Self::TimeDate(Some(time::Date::MIN)),
706
707 #[cfg(feature = "with-time")]
708 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
709 Self::TimeTime(_) => Self::TimeTime(Some(time::Time::MIDNIGHT)),
710
711 #[cfg(feature = "with-time")]
712 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
713 Self::TimeDateTime(_) => Self::TimeDateTime(Some(PrimitiveDateTime::MIN)),
714
715 #[cfg(feature = "with-time")]
716 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
717 Self::TimeDateTimeWithTimeZone(_) => {
718 Self::TimeDateTimeWithTimeZone(Some(OffsetDateTime::UNIX_EPOCH))
719 }
720
721 #[cfg(feature = "with-jiff")]
722 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
723 Self::JiffDate(_) => Self::JiffDate(Some(jiff::civil::date(1970, 1, 1))),
724
725 #[cfg(feature = "with-jiff")]
726 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
727 Self::JiffTime(_) => Self::JiffTime(Some(jiff::civil::time(0, 0, 0, 0))),
728
729 #[cfg(feature = "with-jiff")]
730 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
731 Self::JiffDateTime(_) => {
732 Self::JiffDateTime(Some(jiff::civil::date(1970, 1, 1).at(0, 0, 0, 0).into()))
733 }
734
735 #[cfg(feature = "with-jiff")]
736 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
737 Self::JiffTimestamp(_) => Self::JiffTimestamp(Some(Timestamp::UNIX_EPOCH.into())),
738
739 #[cfg(feature = "with-uuid")]
740 #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
741 Self::Uuid(_) => Self::Uuid(Some(Default::default())),
742
743 #[cfg(feature = "with-rust_decimal")]
744 #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
745 Self::Decimal(_) => Self::Decimal(Some(Default::default())),
746
747 #[cfg(feature = "with-bigdecimal")]
748 #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
749 Self::BigDecimal(_) => Self::BigDecimal(Some(Default::default())),
750
751 #[cfg(feature = "postgres-array")]
752 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
753 Self::Array(ty, _) => Self::Array(ty.clone(), Some(Default::default())),
754
755 #[cfg(feature = "postgres-vector")]
756 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
757 Self::Vector(_) => Self::Vector(Some(vec![].into())),
758
759 #[cfg(feature = "with-ipnetwork")]
760 #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
761 Self::IpNetwork(_) => Self::IpNetwork(Some("0.0.0.0".parse().unwrap())),
762
763 #[cfg(feature = "with-mac_address")]
764 #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
765 Self::MacAddress(_) => Self::MacAddress(Some(Default::default())),
766
767 #[cfg(feature = "postgres-range")]
768 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
769 Self::Range(_) => Self::Range(Some(Default::default())),
770 }
771 }
772
773 pub fn array_type(&self) -> ArrayType {
774 #[allow(unused_imports)]
775 use std::ops::Deref;
776
777 fn array_type_of<V: ValueType>(_: &Option<V>) -> ArrayType {
778 V::array_type()
779 }
780
781 #[allow(dead_code)]
782 fn array_type_of_ref<V: ValueType>(_: Option<&V>) -> ArrayType {
783 V::array_type()
784 }
785
786 match self {
787 Self::Bool(v) => array_type_of(v),
788 Self::TinyInt(v) => array_type_of(v),
789 Self::SmallInt(v) => array_type_of(v),
790 Self::Int(v) => array_type_of(v),
791 Self::BigInt(v) => array_type_of(v),
792 Self::TinyUnsigned(v) => array_type_of(v),
793 Self::SmallUnsigned(v) => array_type_of(v),
794 Self::Unsigned(v) => array_type_of(v),
795 Self::BigUnsigned(v) => array_type_of(v),
796 Self::Float(v) => array_type_of(v),
797 Self::Double(v) => array_type_of(v),
798 Self::String(v) => array_type_of(v),
799
800 #[cfg(feature = "backend-postgres")]
801 Self::Enum(v) => ArrayType::Enum(Box::new(match v {
802 OptionEnum::Some(v) => v.type_name.clone(),
803 OptionEnum::None(type_name) => type_name.clone(),
804 })),
805 #[cfg(not(feature = "backend-postgres"))]
806 Self::Enum(_) => ArrayType::String,
807 Self::Char(v) => array_type_of(v),
808 Self::Bytes(v) => array_type_of(v),
809
810 #[cfg(feature = "with-json")]
811 #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
812 Self::Json(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
813
814 #[cfg(feature = "with-chrono")]
815 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
816 Self::ChronoDate(v) => array_type_of(v),
817
818 #[cfg(feature = "with-chrono")]
819 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
820 Self::ChronoTime(v) => array_type_of(v),
821
822 #[cfg(feature = "with-chrono")]
823 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
824 Self::ChronoDateTime(v) => array_type_of(v),
825
826 #[cfg(feature = "with-chrono")]
827 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
828 Self::ChronoDateTimeUtc(v) => array_type_of(v),
829
830 #[cfg(feature = "with-chrono")]
831 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
832 Self::ChronoDateTimeLocal(v) => array_type_of(v),
833
834 #[cfg(feature = "with-chrono")]
835 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
836 Self::ChronoDateTimeWithTimeZone(v) => array_type_of(v),
837
838 #[cfg(feature = "with-time")]
839 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
840 Self::TimeDate(v) => array_type_of(v),
841
842 #[cfg(feature = "with-time")]
843 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
844 Self::TimeTime(v) => array_type_of(v),
845
846 #[cfg(feature = "with-time")]
847 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
848 Self::TimeDateTime(v) => array_type_of(v),
849
850 #[cfg(feature = "with-time")]
851 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
852 Self::TimeDateTimeWithTimeZone(v) => array_type_of(v),
853
854 #[cfg(feature = "with-jiff")]
855 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
856 Self::JiffDate(v) => array_type_of(v),
857
858 #[cfg(feature = "with-jiff")]
859 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
860 Self::JiffTime(v) => array_type_of(v),
861
862 #[cfg(feature = "with-jiff")]
863 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
864 Self::JiffDateTime(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
865
866 #[cfg(feature = "with-jiff")]
867 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
868 Self::JiffTimestamp(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
869
870 #[cfg(feature = "with-uuid")]
871 #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
872 Self::Uuid(v) => array_type_of(v),
873
874 #[cfg(feature = "with-rust_decimal")]
875 #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
876 Self::Decimal(v) => array_type_of(v),
877
878 #[cfg(feature = "with-bigdecimal")]
879 #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
880 Self::BigDecimal(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
881
882 #[cfg(feature = "postgres-array")]
883 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
884 Self::Array(v, _) => v.clone(),
885
886 #[cfg(feature = "postgres-vector")]
887 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
888 Self::Vector(v) => array_type_of(v),
889
890 #[cfg(feature = "with-ipnetwork")]
891 #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
892 Self::IpNetwork(v) => array_type_of(v),
893
894 #[cfg(feature = "with-mac_address")]
895 #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
896 Self::MacAddress(v) => array_type_of(v),
897
898 #[cfg(feature = "postgres-range")]
899 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
900 Self::Range(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
901 }
902 }
903}
904
905impl From<&[u8]> for Value {
906 fn from(x: &[u8]) -> Value {
907 Value::Bytes(Some(x.into()))
908 }
909}
910
911impl From<&str> for Value {
912 fn from(x: &str) -> Value {
913 Value::String(Some(x.to_owned()))
914 }
915}
916
917impl From<&String> for Value {
918 fn from(x: &String) -> Value {
919 Value::String(Some(x.clone()))
920 }
921}
922
923impl<T> From<Option<T>> for Value
924where
925 T: Into<Value> + Nullable,
926{
927 fn from(x: Option<T>) -> Value {
928 match x {
929 Some(v) => v.into(),
930 None => T::null(),
931 }
932 }
933}
934
935impl From<Cow<'_, str>> for Value {
936 fn from(x: Cow<'_, str>) -> Value {
937 x.into_owned().into()
938 }
939}
940
941impl From<Enum> for Value {
942 fn from(value: Enum) -> Value {
943 Value::Enum(OptionEnum::Some(Box::new(value)))
944 }
945}
946
947impl IntoIterator for Values {
948 type Item = Value;
949 type IntoIter = std::vec::IntoIter<Self::Item>;
950
951 fn into_iter(self) -> Self::IntoIter {
952 self.0.into_iter()
953 }
954}
955
956impl std::fmt::Display for Value {
957 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
958 CommonSqlQueryBuilder.write_value(f, self)
959 }
960}
961
962pub trait ValueType: Sized {
963 fn try_from(v: Value) -> Result<Self, ValueTypeErr>;
964
965 fn unwrap(v: Value) -> Self {
966 Self::try_from(v).unwrap()
967 }
968
969 fn expect(v: Value, msg: &str) -> Self {
970 Self::try_from(v).expect(msg)
971 }
972
973 fn is_option() -> bool {
974 false
975 }
976
977 fn type_name() -> String;
978
979 fn array_type() -> ArrayType;
980
981 fn column_type() -> ColumnType;
982
983 fn enum_type_name() -> Option<&'static str> {
984 None
985 }
986}
987
988impl<T> ValueType for Option<T>
989where
990 T: ValueType + Nullable,
991{
992 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
993 if v == T::null() {
994 Ok(None)
995 } else {
996 Ok(Some(T::try_from(v)?))
997 }
998 }
999
1000 fn is_option() -> bool {
1001 true
1002 }
1003
1004 fn type_name() -> String {
1005 format!("Option<{}>", T::type_name())
1006 }
1007
1008 fn array_type() -> ArrayType {
1009 T::array_type()
1010 }
1011
1012 fn column_type() -> ColumnType {
1013 T::column_type()
1014 }
1015}
1016
1017impl ValueType for Cow<'_, str> {
1018 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
1019 match v {
1020 Value::String(Some(x)) => Ok((x).into()),
1021 _ => Err(ValueTypeErr),
1022 }
1023 }
1024
1025 fn type_name() -> String {
1026 "Cow<str>".into()
1027 }
1028
1029 fn array_type() -> ArrayType {
1030 ArrayType::String
1031 }
1032
1033 fn column_type() -> ColumnType {
1034 ColumnType::String(StringLen::None)
1035 }
1036}
1037
1038#[derive(Debug)]
1039pub struct ValueTypeErr;
1040
1041impl std::error::Error for ValueTypeErr {}
1042
1043impl std::fmt::Display for ValueTypeErr {
1044 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1045 f.write_str("Value type mismatch")
1046 }
1047}
1048
1049#[derive(Clone, Debug, PartialEq)]
1050pub struct Values(pub Vec<Value>);
1051
1052impl Values {
1053 pub fn iter(&self) -> impl Iterator<Item = &Value> {
1054 self.0.iter()
1055 }
1056}
1057
1058pub trait Nullable {
1059 fn null() -> Value;
1060}
1061
1062impl Nullable for &str {
1063 fn null() -> Value {
1064 Value::String(None)
1065 }
1066}
1067
1068impl Nullable for Enum {
1069 fn null() -> Value {
1070 Value::Enum(OptionEnum::None("".into()))
1071 }
1072}
1073
1074impl ValueType for Enum {
1075 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
1076 match v {
1077 Value::Enum(OptionEnum::Some(v)) => Ok(*v),
1078 _ => Err(ValueTypeErr),
1079 }
1080 }
1081
1082 fn type_name() -> String {
1083 "Enum".into()
1084 }
1085
1086 fn array_type() -> ArrayType {
1089 ArrayType::String
1090 }
1091
1092 fn column_type() -> ColumnType {
1093 ColumnType::String(StringLen::None)
1094 }
1095}
1096
1097macro_rules! type_to_value {
1098 ( $type: ty, $name: ident, $col_type: expr ) => {
1099 impl From<$type> for Value {
1100 fn from(x: $type) -> Value {
1101 Value::$name(Some(x))
1102 }
1103 }
1104
1105 impl Nullable for $type {
1106 fn null() -> Value {
1107 Value::$name(None)
1108 }
1109 }
1110
1111 impl ValueType for $type {
1112 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
1113 match v {
1114 Value::$name(Some(x)) => Ok(x),
1115 _ => Err(ValueTypeErr),
1116 }
1117 }
1118
1119 fn type_name() -> String {
1120 stringify!($type).to_owned()
1121 }
1122
1123 fn array_type() -> ArrayType {
1124 ArrayType::$name
1125 }
1126
1127 fn column_type() -> ColumnType {
1128 use ColumnType::*;
1129 $col_type
1130 }
1131 }
1132 };
1133}
1134
1135#[allow(unused_imports)]
1136use type_to_value;
1137
1138type_to_value!(bool, Bool, Boolean);
1139type_to_value!(i8, TinyInt, TinyInteger);
1140type_to_value!(i16, SmallInt, SmallInteger);
1141type_to_value!(i32, Int, Integer);
1142type_to_value!(i64, BigInt, BigInteger);
1143type_to_value!(u8, TinyUnsigned, TinyUnsigned);
1144type_to_value!(u16, SmallUnsigned, SmallUnsigned);
1145type_to_value!(u32, Unsigned, Unsigned);
1146type_to_value!(u64, BigUnsigned, BigUnsigned);
1147type_to_value!(f32, Float, Float);
1148type_to_value!(f64, Double, Double);
1149type_to_value!(char, Char, Char(None));
1150type_to_value!(Vec<u8>, Bytes, VarBinary(StringLen::None));
1151type_to_value!(String, String, String(StringLen::None));
1152
1153#[allow(unused_macros)]
1154macro_rules! type_to_box_value {
1155 ( $type: ty, $name: ident, $col_type: expr ) => {
1156 impl From<$type> for Value {
1157 fn from(x: $type) -> Value {
1158 Value::$name(Some(Box::new(x)))
1159 }
1160 }
1161
1162 impl Nullable for $type {
1163 fn null() -> Value {
1164 Value::$name(None)
1165 }
1166 }
1167
1168 impl ValueType for $type {
1169 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
1170 match v {
1171 Value::$name(Some(x)) => Ok(*x),
1172 _ => Err(ValueTypeErr),
1173 }
1174 }
1175
1176 fn type_name() -> String {
1177 stringify!($type).to_owned()
1178 }
1179
1180 fn array_type() -> ArrayType {
1181 ArrayType::$name
1182 }
1183
1184 fn column_type() -> ColumnType {
1185 use ColumnType::*;
1186 $col_type
1187 }
1188 }
1189 };
1190}
1191
1192#[allow(unused_imports)]
1193use type_to_box_value;