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(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 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-jiff")]
166 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
167 JiffZoned,
168
169 #[cfg(feature = "with-uuid")]
170 #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
171 Uuid,
172
173 #[cfg(feature = "with-rust_decimal")]
174 #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
175 Decimal,
176
177 #[cfg(feature = "with-bigdecimal")]
178 #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
179 BigDecimal,
180
181 #[cfg(feature = "with-ipnetwork")]
182 #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
183 IpNetwork,
184
185 #[cfg(feature = "with-mac_address")]
186 #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
187 MacAddress,
188
189 #[cfg(feature = "postgres-range")]
190 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
191 Range,
192}
193
194pub type EnumTypeName = RcOrArc<str>;
196
197#[derive(Clone, Debug, Eq, PartialEq, Hash)]
198#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
199pub struct Enum {
200 pub type_name: EnumTypeName,
201 pub value: Cow<'static, str>,
202}
203
204#[derive(Debug, Clone, PartialEq, Eq, Hash)]
207#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
208pub enum OptionEnum {
209 Some(Box<Enum>),
210 None(EnumTypeName),
211}
212
213#[derive(Clone, Debug)]
220#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
221#[cfg_attr(not(feature = "hashable-value"), derive(PartialEq))]
222pub enum Value {
223 Bool(Option<bool>),
224 TinyInt(Option<i8>),
225 SmallInt(Option<i16>),
226 Int(Option<i32>),
227 BigInt(Option<i64>),
228 TinyUnsigned(Option<u8>),
229 SmallUnsigned(Option<u16>),
230 Unsigned(Option<u32>),
231 BigUnsigned(Option<u64>),
232 Float(Option<f32>),
233 Double(Option<f64>),
234 String(Option<String>),
235 Enum(OptionEnum),
236 Char(Option<char>),
237
238 #[allow(clippy::box_collection)]
239 Bytes(Option<Vec<u8>>),
240
241 #[cfg(feature = "with-json")]
242 #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
243 Json(Option<Box<Json>>),
244
245 #[cfg(feature = "with-chrono")]
246 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
247 ChronoDate(Option<NaiveDate>),
248
249 #[cfg(feature = "with-chrono")]
250 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
251 ChronoTime(Option<NaiveTime>),
252
253 #[cfg(feature = "with-chrono")]
254 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
255 ChronoDateTime(Option<NaiveDateTime>),
256
257 #[cfg(feature = "with-chrono")]
258 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
259 ChronoDateTimeUtc(Option<DateTime<Utc>>),
260
261 #[cfg(feature = "with-chrono")]
262 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
263 ChronoDateTimeLocal(Option<DateTime<Local>>),
264
265 #[cfg(feature = "with-chrono")]
266 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
267 ChronoDateTimeWithTimeZone(Option<DateTime<FixedOffset>>),
268
269 #[cfg(feature = "with-time")]
270 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
271 TimeDate(Option<time::Date>),
272
273 #[cfg(feature = "with-time")]
274 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
275 TimeTime(Option<time::Time>),
276
277 #[cfg(feature = "with-time")]
278 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
279 TimeDateTime(Option<PrimitiveDateTime>),
280
281 #[cfg(feature = "with-time")]
282 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
283 TimeDateTimeWithTimeZone(Option<OffsetDateTime>),
284
285 #[cfg(feature = "with-jiff")]
286 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
287 JiffDate(Option<jiff::civil::Date>),
288
289 #[cfg(feature = "with-jiff")]
290 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
291 JiffTime(Option<jiff::civil::Time>),
292
293 #[cfg(feature = "with-jiff")]
294 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
295 JiffDateTime(Option<Box<jiff::civil::DateTime>>),
296
297 #[cfg(feature = "with-jiff")]
298 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
299 JiffTimestamp(Option<Box<Timestamp>>),
300
301 #[cfg(feature = "with-jiff")]
302 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
303 JiffZoned(Option<Box<Zoned>>),
304
305 #[cfg(feature = "with-uuid")]
306 #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
307 Uuid(Option<Uuid>),
308
309 #[cfg(feature = "with-rust_decimal")]
310 #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
311 Decimal(Option<Decimal>),
312
313 #[cfg(feature = "with-bigdecimal")]
314 #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
315 BigDecimal(Option<Box<BigDecimal>>),
316
317 #[cfg(feature = "postgres-array")]
318 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
319 Array(ArrayType, Option<Box<Vec<Value>>>),
320
321 #[cfg(feature = "postgres-vector")]
322 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
323 Vector(Option<pgvector::Vector>),
324
325 #[cfg(feature = "with-ipnetwork")]
326 #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
327 IpNetwork(Option<IpNetwork>),
328
329 #[cfg(feature = "with-mac_address")]
330 #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
331 MacAddress(Option<MacAddress>),
332
333 #[cfg(feature = "postgres-range")]
334 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
335 Range(Option<Box<RangeType>>),
336}
337
338pub const VALUE_SIZE: usize = check_value_size();
348const MAX_VALUE_SIZE: usize = 32;
349
350const fn check_value_size() -> usize {
351 if std::mem::size_of::<Value>() > MAX_VALUE_SIZE {
352 panic!(
353 "the size of Value shouldn't be greater than the expected MAX_VALUE_SIZE (32 bytes by default)"
354 )
355 }
356 std::mem::size_of::<Value>()
357}
358
359impl Value {
360 pub fn unwrap<T>(self) -> T
361 where
362 T: ValueType,
363 {
364 T::unwrap(self)
365 }
366
367 pub fn expect<T>(self, msg: &str) -> T
368 where
369 T: ValueType,
370 {
371 T::expect(self, msg)
372 }
373
374 pub fn as_null(&self) -> Self {
388 match self {
389 Self::Bool(_) => Self::Bool(None),
390 Self::TinyInt(_) => Self::TinyInt(None),
391 Self::SmallInt(_) => Self::SmallInt(None),
392 Self::Int(_) => Self::Int(None),
393 Self::BigInt(_) => Self::BigInt(None),
394 Self::TinyUnsigned(_) => Self::TinyUnsigned(None),
395 Self::SmallUnsigned(_) => Self::SmallUnsigned(None),
396 Self::Unsigned(_) => Self::Unsigned(None),
397 Self::BigUnsigned(_) => Self::BigUnsigned(None),
398 Self::Float(_) => Self::Float(None),
399 Self::Double(_) => Self::Double(None),
400 Self::String(_) => Self::String(None),
401 Self::Enum(OptionEnum::Some(v)) => Self::Enum(OptionEnum::None(v.type_name.clone())),
402 Self::Enum(OptionEnum::None(type_name)) => {
403 Self::Enum(OptionEnum::None(type_name.clone()))
404 }
405 Self::Char(_) => Self::Char(None),
406 Self::Bytes(_) => Self::Bytes(None),
407
408 #[cfg(feature = "with-json")]
409 #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
410 Self::Json(_) => Self::Json(None),
411
412 #[cfg(feature = "with-chrono")]
413 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
414 Self::ChronoDate(_) => Self::ChronoDate(None),
415
416 #[cfg(feature = "with-chrono")]
417 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
418 Self::ChronoTime(_) => Self::ChronoTime(None),
419
420 #[cfg(feature = "with-chrono")]
421 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
422 Self::ChronoDateTime(_) => Self::ChronoDateTime(None),
423
424 #[cfg(feature = "with-chrono")]
425 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
426 Self::ChronoDateTimeUtc(_) => Self::ChronoDateTimeUtc(None),
427
428 #[cfg(feature = "with-chrono")]
429 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
430 Self::ChronoDateTimeLocal(_) => Self::ChronoDateTimeLocal(None),
431
432 #[cfg(feature = "with-chrono")]
433 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
434 Self::ChronoDateTimeWithTimeZone(_) => Self::ChronoDateTimeWithTimeZone(None),
435
436 #[cfg(feature = "with-time")]
437 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
438 Self::TimeDate(_) => Self::TimeDate(None),
439
440 #[cfg(feature = "with-time")]
441 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
442 Self::TimeTime(_) => Self::TimeTime(None),
443
444 #[cfg(feature = "with-time")]
445 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
446 Self::TimeDateTime(_) => Self::TimeDateTime(None),
447
448 #[cfg(feature = "with-time")]
449 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
450 Self::TimeDateTimeWithTimeZone(_) => Self::TimeDateTimeWithTimeZone(None),
451
452 #[cfg(feature = "with-jiff")]
453 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
454 Self::JiffDate(_) => Self::JiffDate(None),
455
456 #[cfg(feature = "with-jiff")]
457 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
458 Self::JiffTime(_) => Self::JiffTime(None),
459
460 #[cfg(feature = "with-jiff")]
461 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
462 Self::JiffDateTime(_) => Self::JiffDateTime(None),
463
464 #[cfg(feature = "with-jiff")]
465 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
466 Self::JiffTimestamp(_) => Self::JiffTimestamp(None),
467
468 #[cfg(feature = "with-jiff")]
469 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
470 Self::JiffZoned(_) => Self::JiffZoned(None),
471
472 #[cfg(feature = "with-uuid")]
473 #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
474 Self::Uuid(_) => Self::Uuid(None),
475
476 #[cfg(feature = "with-rust_decimal")]
477 #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
478 Self::Decimal(_) => Self::Decimal(None),
479
480 #[cfg(feature = "with-bigdecimal")]
481 #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
482 Self::BigDecimal(_) => Self::BigDecimal(None),
483
484 #[cfg(feature = "postgres-array")]
485 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
486 Self::Array(ty, _) => Self::Array(ty.clone(), None),
487
488 #[cfg(feature = "postgres-vector")]
489 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
490 Self::Vector(_) => Self::Vector(None),
491
492 #[cfg(feature = "with-ipnetwork")]
493 #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
494 Self::IpNetwork(_) => Self::IpNetwork(None),
495
496 #[cfg(feature = "with-mac_address")]
497 #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
498 Self::MacAddress(_) => Self::MacAddress(None),
499
500 #[cfg(feature = "postgres-range")]
501 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
502 Self::Range(_) => Self::Range(None),
503 }
504 }
505
506 pub fn dummy_value(&self) -> Self {
516 match self {
517 Self::Bool(_) => Self::Bool(Some(Default::default())),
518 Self::TinyInt(_) => Self::TinyInt(Some(Default::default())),
519 Self::SmallInt(_) => Self::SmallInt(Some(Default::default())),
520 Self::Int(_) => Self::Int(Some(Default::default())),
521 Self::BigInt(_) => Self::BigInt(Some(Default::default())),
522 Self::TinyUnsigned(_) => Self::TinyUnsigned(Some(Default::default())),
523 Self::SmallUnsigned(_) => Self::SmallUnsigned(Some(Default::default())),
524 Self::Unsigned(_) => Self::Unsigned(Some(Default::default())),
525 Self::BigUnsigned(_) => Self::BigUnsigned(Some(Default::default())),
526 Self::Float(_) => Self::Float(Some(Default::default())),
527 Self::Double(_) => Self::Double(Some(Default::default())),
528 Self::String(_) => Self::String(Some(Default::default())),
529 Self::Enum(v) => {
530 let type_name = match v {
531 OptionEnum::Some(v) => v.type_name.clone(),
532 OptionEnum::None(type_name) => type_name.clone(),
533 };
534 Self::Enum(OptionEnum::Some(Box::new(Enum {
535 type_name,
536 value: Cow::Borrowed(""),
537 })))
538 }
539 Self::Char(_) => Self::Char(Some(Default::default())),
540 Self::Bytes(_) => Self::Bytes(Some(Default::default())),
541
542 #[cfg(feature = "with-json")]
543 #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
544 Self::Json(_) => Self::Json(Some(Default::default())),
545
546 #[cfg(feature = "with-chrono")]
547 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
548 Self::ChronoDate(_) => Self::ChronoDate(Some(Default::default())),
549
550 #[cfg(feature = "with-chrono")]
551 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
552 Self::ChronoTime(_) => Self::ChronoTime(Some(Default::default())),
553
554 #[cfg(feature = "with-chrono")]
555 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
556 Self::ChronoDateTime(_) => Self::ChronoDateTime(Some(Default::default())),
557
558 #[cfg(feature = "with-chrono")]
559 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
560 Self::ChronoDateTimeUtc(_) => Self::ChronoDateTimeUtc(Some(Default::default())),
561
562 #[cfg(feature = "with-chrono")]
563 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
564 Self::ChronoDateTimeLocal(_) => Self::ChronoDateTimeLocal(Some(Default::default())),
565
566 #[cfg(feature = "with-chrono")]
567 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
568 Self::ChronoDateTimeWithTimeZone(_) => {
569 Self::ChronoDateTimeWithTimeZone(Some(Default::default()))
570 }
571
572 #[cfg(feature = "with-time")]
573 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
574 Self::TimeDate(_) => Self::TimeDate(Some(time::Date::MIN)),
575
576 #[cfg(feature = "with-time")]
577 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
578 Self::TimeTime(_) => Self::TimeTime(Some(time::Time::MIDNIGHT)),
579
580 #[cfg(feature = "with-time")]
581 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
582 Self::TimeDateTime(_) => Self::TimeDateTime(Some(PrimitiveDateTime::MIN)),
583
584 #[cfg(feature = "with-time")]
585 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
586 Self::TimeDateTimeWithTimeZone(_) => {
587 Self::TimeDateTimeWithTimeZone(Some(OffsetDateTime::UNIX_EPOCH))
588 }
589
590 #[cfg(feature = "with-jiff")]
591 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
592 Self::JiffDate(_) => Self::JiffDate(Some(jiff::civil::date(1970, 1, 1))),
593
594 #[cfg(feature = "with-jiff")]
595 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
596 Self::JiffTime(_) => Self::JiffTime(Some(jiff::civil::time(0, 0, 0, 0))),
597
598 #[cfg(feature = "with-jiff")]
599 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
600 Self::JiffDateTime(_) => {
601 Self::JiffDateTime(Some(jiff::civil::date(1970, 1, 1).at(0, 0, 0, 0).into()))
602 }
603
604 #[cfg(feature = "with-jiff")]
605 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
606 Self::JiffTimestamp(_) => Self::JiffTimestamp(Some(Timestamp::UNIX_EPOCH.into())),
607
608 #[cfg(feature = "with-jiff")]
609 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
610 Self::JiffZoned(_) => Self::JiffZoned(Some(
611 Timestamp::UNIX_EPOCH
612 .to_zoned(jiff::tz::TimeZone::UTC)
613 .into(),
614 )),
615
616 #[cfg(feature = "with-uuid")]
617 #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
618 Self::Uuid(_) => Self::Uuid(Some(Default::default())),
619
620 #[cfg(feature = "with-rust_decimal")]
621 #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
622 Self::Decimal(_) => Self::Decimal(Some(Default::default())),
623
624 #[cfg(feature = "with-bigdecimal")]
625 #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
626 Self::BigDecimal(_) => Self::BigDecimal(Some(Default::default())),
627
628 #[cfg(feature = "postgres-array")]
629 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
630 Self::Array(ty, _) => Self::Array(ty.clone(), Some(Default::default())),
631
632 #[cfg(feature = "postgres-vector")]
633 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
634 Self::Vector(_) => Self::Vector(Some(vec![].into())),
635
636 #[cfg(feature = "with-ipnetwork")]
637 #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
638 Self::IpNetwork(_) => Self::IpNetwork(Some("0.0.0.0".parse().unwrap())),
639
640 #[cfg(feature = "with-mac_address")]
641 #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
642 Self::MacAddress(_) => Self::MacAddress(Some(Default::default())),
643
644 #[cfg(feature = "postgres-range")]
645 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
646 Self::Range(_) => Self::Range(Some(Default::default())),
647 }
648 }
649
650 pub fn array_type(&self) -> ArrayType {
651 #[allow(unused_imports)]
652 use std::ops::Deref;
653
654 fn array_type_of<V: ValueType>(_: &Option<V>) -> ArrayType {
655 V::array_type()
656 }
657
658 #[allow(dead_code)]
659 fn array_type_of_ref<V: ValueType>(_: Option<&V>) -> ArrayType {
660 V::array_type()
661 }
662
663 match self {
664 Self::Bool(v) => array_type_of(v),
665 Self::TinyInt(v) => array_type_of(v),
666 Self::SmallInt(v) => array_type_of(v),
667 Self::Int(v) => array_type_of(v),
668 Self::BigInt(v) => array_type_of(v),
669 Self::TinyUnsigned(v) => array_type_of(v),
670 Self::SmallUnsigned(v) => array_type_of(v),
671 Self::Unsigned(v) => array_type_of(v),
672 Self::BigUnsigned(v) => array_type_of(v),
673 Self::Float(v) => array_type_of(v),
674 Self::Double(v) => array_type_of(v),
675 Self::String(v) => array_type_of(v),
676
677 #[cfg(feature = "backend-postgres")]
678 Self::Enum(v) => ArrayType::Enum(Box::new(match v {
679 OptionEnum::Some(v) => v.type_name.clone(),
680 OptionEnum::None(type_name) => type_name.clone(),
681 })),
682 #[cfg(not(feature = "backend-postgres"))]
683 Self::Enum(_) => ArrayType::String,
684 Self::Char(v) => array_type_of(v),
685 Self::Bytes(v) => array_type_of(v),
686
687 #[cfg(feature = "with-json")]
688 #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
689 Self::Json(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
690
691 #[cfg(feature = "with-chrono")]
692 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
693 Self::ChronoDate(v) => array_type_of(v),
694
695 #[cfg(feature = "with-chrono")]
696 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
697 Self::ChronoTime(v) => array_type_of(v),
698
699 #[cfg(feature = "with-chrono")]
700 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
701 Self::ChronoDateTime(v) => array_type_of(v),
702
703 #[cfg(feature = "with-chrono")]
704 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
705 Self::ChronoDateTimeUtc(v) => array_type_of(v),
706
707 #[cfg(feature = "with-chrono")]
708 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
709 Self::ChronoDateTimeLocal(v) => array_type_of(v),
710
711 #[cfg(feature = "with-chrono")]
712 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
713 Self::ChronoDateTimeWithTimeZone(v) => array_type_of(v),
714
715 #[cfg(feature = "with-time")]
716 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
717 Self::TimeDate(v) => array_type_of(v),
718
719 #[cfg(feature = "with-time")]
720 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
721 Self::TimeTime(v) => array_type_of(v),
722
723 #[cfg(feature = "with-time")]
724 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
725 Self::TimeDateTime(v) => array_type_of(v),
726
727 #[cfg(feature = "with-time")]
728 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
729 Self::TimeDateTimeWithTimeZone(v) => array_type_of(v),
730
731 #[cfg(feature = "with-jiff")]
732 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
733 Self::JiffDate(v) => array_type_of(v),
734
735 #[cfg(feature = "with-jiff")]
736 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
737 Self::JiffTime(v) => array_type_of(v),
738
739 #[cfg(feature = "with-jiff")]
740 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
741 Self::JiffDateTime(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
742
743 #[cfg(feature = "with-jiff")]
744 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
745 Self::JiffTimestamp(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
746
747 #[cfg(feature = "with-jiff")]
748 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
749 Self::JiffZoned(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
750
751 #[cfg(feature = "with-uuid")]
752 #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
753 Self::Uuid(v) => array_type_of(v),
754
755 #[cfg(feature = "with-rust_decimal")]
756 #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
757 Self::Decimal(v) => array_type_of(v),
758
759 #[cfg(feature = "with-bigdecimal")]
760 #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
761 Self::BigDecimal(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
762
763 #[cfg(feature = "postgres-array")]
764 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
765 Self::Array(v, _) => v.clone(),
766
767 #[cfg(feature = "postgres-vector")]
768 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
769 Self::Vector(v) => array_type_of(v),
770
771 #[cfg(feature = "with-ipnetwork")]
772 #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
773 Self::IpNetwork(v) => array_type_of(v),
774
775 #[cfg(feature = "with-mac_address")]
776 #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
777 Self::MacAddress(v) => array_type_of(v),
778
779 #[cfg(feature = "postgres-range")]
780 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
781 Self::Range(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
782 }
783 }
784}
785
786impl From<&[u8]> for Value {
787 fn from(x: &[u8]) -> Value {
788 Value::Bytes(Some(x.into()))
789 }
790}
791
792impl From<&str> for Value {
793 fn from(x: &str) -> Value {
794 Value::String(Some(x.to_owned()))
795 }
796}
797
798impl From<&String> for Value {
799 fn from(x: &String) -> Value {
800 Value::String(Some(x.clone()))
801 }
802}
803
804impl<T> From<Option<T>> for Value
805where
806 T: Into<Value> + Nullable,
807{
808 fn from(x: Option<T>) -> Value {
809 match x {
810 Some(v) => v.into(),
811 None => T::null(),
812 }
813 }
814}
815
816impl From<Cow<'_, str>> for Value {
817 fn from(x: Cow<'_, str>) -> Value {
818 x.into_owned().into()
819 }
820}
821
822impl From<Enum> for Value {
823 fn from(value: Enum) -> Value {
824 Value::Enum(OptionEnum::Some(Box::new(value)))
825 }
826}
827
828impl IntoIterator for Values {
829 type Item = Value;
830 type IntoIter = std::vec::IntoIter<Self::Item>;
831
832 fn into_iter(self) -> Self::IntoIter {
833 self.0.into_iter()
834 }
835}
836
837impl std::fmt::Display for Value {
838 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
839 CommonSqlQueryBuilder.write_value(f, self)
840 }
841}
842
843pub trait ValueType: Sized {
844 fn try_from(v: Value) -> Result<Self, ValueTypeErr>;
845
846 fn unwrap(v: Value) -> Self {
847 Self::try_from(v).unwrap()
848 }
849
850 fn expect(v: Value, msg: &str) -> Self {
851 Self::try_from(v).expect(msg)
852 }
853
854 fn is_option() -> bool {
855 false
856 }
857
858 fn type_name() -> String;
859
860 fn array_type() -> ArrayType;
861
862 fn column_type() -> ColumnType;
863
864 fn enum_type_name() -> Option<&'static str> {
865 None
866 }
867}
868
869impl<T> ValueType for Option<T>
870where
871 T: ValueType + Nullable,
872{
873 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
874 if v == T::null() {
875 Ok(None)
876 } else {
877 Ok(Some(T::try_from(v)?))
878 }
879 }
880
881 fn is_option() -> bool {
882 true
883 }
884
885 fn type_name() -> String {
886 format!("Option<{}>", T::type_name())
887 }
888
889 fn array_type() -> ArrayType {
890 T::array_type()
891 }
892
893 fn column_type() -> ColumnType {
894 T::column_type()
895 }
896}
897
898impl ValueType for Cow<'_, str> {
899 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
900 match v {
901 Value::String(Some(x)) => Ok((x).into()),
902 _ => Err(ValueTypeErr),
903 }
904 }
905
906 fn type_name() -> String {
907 "Cow<str>".into()
908 }
909
910 fn array_type() -> ArrayType {
911 ArrayType::String
912 }
913
914 fn column_type() -> ColumnType {
915 ColumnType::String(StringLen::None)
916 }
917}
918
919#[derive(Debug)]
920pub struct ValueTypeErr;
921
922impl std::error::Error for ValueTypeErr {}
923
924impl std::fmt::Display for ValueTypeErr {
925 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
926 f.write_str("Value type mismatch")
927 }
928}
929
930#[derive(Clone, Debug, PartialEq)]
931pub struct Values(pub Vec<Value>);
932
933impl Values {
934 pub fn iter(&self) -> impl Iterator<Item = &Value> {
935 self.0.iter()
936 }
937}
938
939pub trait Nullable {
940 fn null() -> Value;
941}
942
943impl Nullable for &str {
944 fn null() -> Value {
945 Value::String(None)
946 }
947}
948
949impl Nullable for Enum {
950 fn null() -> Value {
951 Value::Enum(OptionEnum::None("".into()))
952 }
953}
954
955impl ValueType for Enum {
956 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
957 match v {
958 Value::Enum(OptionEnum::Some(v)) => Ok(*v),
959 _ => Err(ValueTypeErr),
960 }
961 }
962
963 fn type_name() -> String {
964 "Enum".into()
965 }
966
967 fn array_type() -> ArrayType {
970 ArrayType::String
971 }
972
973 fn column_type() -> ColumnType {
974 ColumnType::String(StringLen::None)
975 }
976}
977
978macro_rules! type_to_value {
979 ( $type: ty, $name: ident, $col_type: expr ) => {
980 impl From<$type> for Value {
981 fn from(x: $type) -> Value {
982 Value::$name(Some(x))
983 }
984 }
985
986 impl Nullable for $type {
987 fn null() -> Value {
988 Value::$name(None)
989 }
990 }
991
992 impl ValueType for $type {
993 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
994 match v {
995 Value::$name(Some(x)) => Ok(x),
996 _ => Err(ValueTypeErr),
997 }
998 }
999
1000 fn type_name() -> String {
1001 stringify!($type).to_owned()
1002 }
1003
1004 fn array_type() -> ArrayType {
1005 ArrayType::$name
1006 }
1007
1008 fn column_type() -> ColumnType {
1009 use ColumnType::*;
1010 $col_type
1011 }
1012 }
1013 };
1014}
1015
1016#[allow(unused_imports)]
1017use type_to_value;
1018
1019type_to_value!(bool, Bool, Boolean);
1020type_to_value!(i8, TinyInt, TinyInteger);
1021type_to_value!(i16, SmallInt, SmallInteger);
1022type_to_value!(i32, Int, Integer);
1023type_to_value!(i64, BigInt, BigInteger);
1024type_to_value!(u8, TinyUnsigned, TinyUnsigned);
1025type_to_value!(u16, SmallUnsigned, SmallUnsigned);
1026type_to_value!(u32, Unsigned, Unsigned);
1027type_to_value!(u64, BigUnsigned, BigUnsigned);
1028type_to_value!(f32, Float, Float);
1029type_to_value!(f64, Double, Double);
1030type_to_value!(char, Char, Char(None));
1031type_to_value!(Vec<u8>, Bytes, VarBinary(StringLen::None));
1032type_to_value!(String, String, String(StringLen::None));
1033
1034#[allow(unused_macros)]
1035macro_rules! type_to_box_value {
1036 ( $type: ty, $name: ident, $col_type: expr ) => {
1037 impl From<$type> for Value {
1038 fn from(x: $type) -> Value {
1039 Value::$name(Some(Box::new(x)))
1040 }
1041 }
1042
1043 impl Nullable for $type {
1044 fn null() -> Value {
1045 Value::$name(None)
1046 }
1047 }
1048
1049 impl ValueType for $type {
1050 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
1051 match v {
1052 Value::$name(Some(x)) => Ok(*x),
1053 _ => Err(ValueTypeErr),
1054 }
1055 }
1056
1057 fn type_name() -> String {
1058 stringify!($type).to_owned()
1059 }
1060
1061 fn array_type() -> ArrayType {
1062 ArrayType::$name
1063 }
1064
1065 fn column_type() -> ColumnType {
1066 use ColumnType::*;
1067 $col_type
1068 }
1069 }
1070 };
1071}
1072
1073#[allow(unused_imports)]
1074use type_to_box_value;