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