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