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