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<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
318#[cfg(feature = "with-json")]
319const EXPECTED_VALUE_SIZE: usize = {
320 if size_of::<Option<Json>>() > MAX_VALUE_SIZE {
321 size_of::<Option<Json>>()
322 } else {
323 MAX_VALUE_SIZE
324 }
325};
326#[cfg(not(feature = "with-json"))]
327const EXPECTED_VALUE_SIZE: usize = MAX_VALUE_SIZE;
328
329const fn check_value_size() -> usize {
330 if std::mem::size_of::<Value>() > EXPECTED_VALUE_SIZE {
331 panic!(
332 "the size of Value shouldn't be greater than the expected MAX_VALUE_SIZE (32 bytes by default)"
333 )
334 }
335 std::mem::size_of::<Value>()
336}
337
338impl Value {
339 pub fn unwrap<T>(self) -> T
340 where
341 T: ValueType,
342 {
343 T::unwrap(self)
344 }
345
346 pub fn expect<T>(self, msg: &str) -> T
347 where
348 T: ValueType,
349 {
350 T::expect(self, msg)
351 }
352
353 pub fn as_null(&self) -> Self {
367 match self {
368 Self::Bool(_) => Self::Bool(None),
369 Self::TinyInt(_) => Self::TinyInt(None),
370 Self::SmallInt(_) => Self::SmallInt(None),
371 Self::Int(_) => Self::Int(None),
372 Self::BigInt(_) => Self::BigInt(None),
373 Self::TinyUnsigned(_) => Self::TinyUnsigned(None),
374 Self::SmallUnsigned(_) => Self::SmallUnsigned(None),
375 Self::Unsigned(_) => Self::Unsigned(None),
376 Self::BigUnsigned(_) => Self::BigUnsigned(None),
377 Self::Float(_) => Self::Float(None),
378 Self::Double(_) => Self::Double(None),
379 Self::String(_) => Self::String(None),
380 Self::Char(_) => Self::Char(None),
381 Self::Bytes(_) => Self::Bytes(None),
382
383 #[cfg(feature = "with-json")]
384 #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
385 Self::Json(_) => Self::Json(None),
386
387 #[cfg(feature = "with-chrono")]
388 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
389 Self::ChronoDate(_) => Self::ChronoDate(None),
390
391 #[cfg(feature = "with-chrono")]
392 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
393 Self::ChronoTime(_) => Self::ChronoTime(None),
394
395 #[cfg(feature = "with-chrono")]
396 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
397 Self::ChronoDateTime(_) => Self::ChronoDateTime(None),
398
399 #[cfg(feature = "with-chrono")]
400 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
401 Self::ChronoDateTimeUtc(_) => Self::ChronoDateTimeUtc(None),
402
403 #[cfg(feature = "with-chrono")]
404 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
405 Self::ChronoDateTimeLocal(_) => Self::ChronoDateTimeLocal(None),
406
407 #[cfg(feature = "with-chrono")]
408 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
409 Self::ChronoDateTimeWithTimeZone(_) => Self::ChronoDateTimeWithTimeZone(None),
410
411 #[cfg(feature = "with-time")]
412 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
413 Self::TimeDate(_) => Self::TimeDate(None),
414
415 #[cfg(feature = "with-time")]
416 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
417 Self::TimeTime(_) => Self::TimeTime(None),
418
419 #[cfg(feature = "with-time")]
420 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
421 Self::TimeDateTime(_) => Self::TimeDateTime(None),
422
423 #[cfg(feature = "with-time")]
424 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
425 Self::TimeDateTimeWithTimeZone(_) => Self::TimeDateTimeWithTimeZone(None),
426
427 #[cfg(feature = "with-jiff")]
428 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
429 Self::JiffDate(_) => Self::JiffDate(None),
430
431 #[cfg(feature = "with-jiff")]
432 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
433 Self::JiffTime(_) => Self::JiffTime(None),
434
435 #[cfg(feature = "with-jiff")]
436 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
437 Self::JiffDateTime(_) => Self::JiffDateTime(None),
438
439 #[cfg(feature = "with-jiff")]
440 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
441 Self::JiffTimestamp(_) => Self::JiffTimestamp(None),
442
443 #[cfg(feature = "with-jiff")]
444 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
445 Self::JiffZoned(_) => Self::JiffZoned(None),
446
447 #[cfg(feature = "with-uuid")]
448 #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
449 Self::Uuid(_) => Self::Uuid(None),
450
451 #[cfg(feature = "with-rust_decimal")]
452 #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
453 Self::Decimal(_) => Self::Decimal(None),
454
455 #[cfg(feature = "with-bigdecimal")]
456 #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
457 Self::BigDecimal(_) => Self::BigDecimal(None),
458
459 #[cfg(feature = "postgres-array")]
460 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
461 Self::Array(ty, _) => Self::Array(ty.clone(), None),
462
463 #[cfg(feature = "postgres-vector")]
464 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
465 Self::Vector(_) => Self::Vector(None),
466
467 #[cfg(feature = "with-ipnetwork")]
468 #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
469 Self::IpNetwork(_) => Self::IpNetwork(None),
470
471 #[cfg(feature = "with-mac_address")]
472 #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
473 Self::MacAddress(_) => Self::MacAddress(None),
474
475 #[cfg(feature = "postgres-range")]
476 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
477 Self::Range(_) => Self::Range(None),
478 }
479 }
480
481 pub fn dummy_value(&self) -> Self {
491 match self {
492 Self::Bool(_) => Self::Bool(Some(Default::default())),
493 Self::TinyInt(_) => Self::TinyInt(Some(Default::default())),
494 Self::SmallInt(_) => Self::SmallInt(Some(Default::default())),
495 Self::Int(_) => Self::Int(Some(Default::default())),
496 Self::BigInt(_) => Self::BigInt(Some(Default::default())),
497 Self::TinyUnsigned(_) => Self::TinyUnsigned(Some(Default::default())),
498 Self::SmallUnsigned(_) => Self::SmallUnsigned(Some(Default::default())),
499 Self::Unsigned(_) => Self::Unsigned(Some(Default::default())),
500 Self::BigUnsigned(_) => Self::BigUnsigned(Some(Default::default())),
501 Self::Float(_) => Self::Float(Some(Default::default())),
502 Self::Double(_) => Self::Double(Some(Default::default())),
503 Self::String(_) => Self::String(Some(Default::default())),
504 Self::Char(_) => Self::Char(Some(Default::default())),
505 Self::Bytes(_) => Self::Bytes(Some(Default::default())),
506
507 #[cfg(feature = "with-json")]
508 #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
509 Self::Json(_) => Self::Json(Some(Default::default())),
510
511 #[cfg(feature = "with-chrono")]
512 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
513 Self::ChronoDate(_) => Self::ChronoDate(Some(Default::default())),
514
515 #[cfg(feature = "with-chrono")]
516 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
517 Self::ChronoTime(_) => Self::ChronoTime(Some(Default::default())),
518
519 #[cfg(feature = "with-chrono")]
520 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
521 Self::ChronoDateTime(_) => Self::ChronoDateTime(Some(Default::default())),
522
523 #[cfg(feature = "with-chrono")]
524 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
525 Self::ChronoDateTimeUtc(_) => Self::ChronoDateTimeUtc(Some(Default::default())),
526
527 #[cfg(feature = "with-chrono")]
528 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
529 Self::ChronoDateTimeLocal(_) => Self::ChronoDateTimeLocal(Some(Default::default())),
530
531 #[cfg(feature = "with-chrono")]
532 #[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
533 Self::ChronoDateTimeWithTimeZone(_) => {
534 Self::ChronoDateTimeWithTimeZone(Some(Default::default()))
535 }
536
537 #[cfg(feature = "with-time")]
538 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
539 Self::TimeDate(_) => Self::TimeDate(Some(time::Date::MIN)),
540
541 #[cfg(feature = "with-time")]
542 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
543 Self::TimeTime(_) => Self::TimeTime(Some(time::Time::MIDNIGHT)),
544
545 #[cfg(feature = "with-time")]
546 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
547 Self::TimeDateTime(_) => Self::TimeDateTime(Some(PrimitiveDateTime::MIN)),
548
549 #[cfg(feature = "with-time")]
550 #[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
551 Self::TimeDateTimeWithTimeZone(_) => {
552 Self::TimeDateTimeWithTimeZone(Some(OffsetDateTime::UNIX_EPOCH))
553 }
554
555 #[cfg(feature = "with-jiff")]
556 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
557 Self::JiffDate(_) => Self::JiffDate(Some(jiff::civil::date(1970, 1, 1))),
558
559 #[cfg(feature = "with-jiff")]
560 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
561 Self::JiffTime(_) => Self::JiffTime(Some(jiff::civil::time(0, 0, 0, 0))),
562
563 #[cfg(feature = "with-jiff")]
564 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
565 Self::JiffDateTime(_) => {
566 Self::JiffDateTime(Some(jiff::civil::date(1970, 1, 1).at(0, 0, 0, 0).into()))
567 }
568
569 #[cfg(feature = "with-jiff")]
570 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
571 Self::JiffTimestamp(_) => Self::JiffTimestamp(Some(Timestamp::UNIX_EPOCH.into())),
572
573 #[cfg(feature = "with-jiff")]
574 #[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
575 Self::JiffZoned(_) => Self::JiffZoned(Some(
576 Timestamp::UNIX_EPOCH
577 .to_zoned(jiff::tz::TimeZone::UTC)
578 .into(),
579 )),
580
581 #[cfg(feature = "with-uuid")]
582 #[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
583 Self::Uuid(_) => Self::Uuid(Some(Default::default())),
584
585 #[cfg(feature = "with-rust_decimal")]
586 #[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
587 Self::Decimal(_) => Self::Decimal(Some(Default::default())),
588
589 #[cfg(feature = "with-bigdecimal")]
590 #[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
591 Self::BigDecimal(_) => Self::BigDecimal(Some(Default::default())),
592
593 #[cfg(feature = "postgres-array")]
594 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
595 Self::Array(ty, _) => Self::Array(ty.clone(), Some(Default::default())),
596
597 #[cfg(feature = "postgres-vector")]
598 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
599 Self::Vector(_) => Self::Vector(Some(vec![].into())),
600
601 #[cfg(feature = "with-ipnetwork")]
602 #[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
603 Self::IpNetwork(_) => Self::IpNetwork(Some("0.0.0.0".parse().unwrap())),
604
605 #[cfg(feature = "with-mac_address")]
606 #[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
607 Self::MacAddress(_) => Self::MacAddress(Some(Default::default())),
608
609 #[cfg(feature = "postgres-range")]
610 #[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
611 Self::Range(_) => Self::Range(Some(Default::default())),
612 }
613 }
614}
615
616impl From<&[u8]> for Value {
617 fn from(x: &[u8]) -> Value {
618 Value::Bytes(Some(x.into()))
619 }
620}
621
622impl From<&str> for Value {
623 fn from(x: &str) -> Value {
624 Value::String(Some(x.to_owned()))
625 }
626}
627
628impl From<&String> for Value {
629 fn from(x: &String) -> Value {
630 Value::String(Some(x.clone()))
631 }
632}
633
634impl<T> From<Option<T>> for Value
635where
636 T: Into<Value> + Nullable,
637{
638 fn from(x: Option<T>) -> Value {
639 match x {
640 Some(v) => v.into(),
641 None => T::null(),
642 }
643 }
644}
645
646impl From<Cow<'_, str>> for Value {
647 fn from(x: Cow<'_, str>) -> Value {
648 x.into_owned().into()
649 }
650}
651
652impl IntoIterator for Values {
653 type Item = Value;
654 type IntoIter = std::vec::IntoIter<Self::Item>;
655
656 fn into_iter(self) -> Self::IntoIter {
657 self.0.into_iter()
658 }
659}
660
661impl std::fmt::Display for Value {
662 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
663 CommonSqlQueryBuilder.write_value(f, self)
664 }
665}
666
667pub trait ValueType: Sized {
668 fn try_from(v: Value) -> Result<Self, ValueTypeErr>;
669
670 fn unwrap(v: Value) -> Self {
671 Self::try_from(v).unwrap()
672 }
673
674 fn expect(v: Value, msg: &str) -> Self {
675 Self::try_from(v).expect(msg)
676 }
677
678 fn is_option() -> bool {
679 false
680 }
681
682 fn type_name() -> String;
683
684 fn array_type() -> ArrayType;
685
686 fn column_type() -> ColumnType;
687
688 fn enum_type_name() -> Option<&'static str> {
689 None
690 }
691}
692
693impl<T> ValueType for Option<T>
694where
695 T: ValueType + Nullable,
696{
697 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
698 if v == T::null() {
699 Ok(None)
700 } else {
701 Ok(Some(T::try_from(v)?))
702 }
703 }
704
705 fn is_option() -> bool {
706 true
707 }
708
709 fn type_name() -> String {
710 format!("Option<{}>", T::type_name())
711 }
712
713 fn array_type() -> ArrayType {
714 T::array_type()
715 }
716
717 fn column_type() -> ColumnType {
718 T::column_type()
719 }
720}
721
722impl ValueType for Cow<'_, str> {
723 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
724 match v {
725 Value::String(Some(x)) => Ok((x).into()),
726 _ => Err(ValueTypeErr),
727 }
728 }
729
730 fn type_name() -> String {
731 "Cow<str>".into()
732 }
733
734 fn array_type() -> ArrayType {
735 ArrayType::String
736 }
737
738 fn column_type() -> ColumnType {
739 ColumnType::String(StringLen::None)
740 }
741}
742
743#[derive(Debug)]
744pub struct ValueTypeErr;
745
746impl std::error::Error for ValueTypeErr {}
747
748impl std::fmt::Display for ValueTypeErr {
749 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
750 f.write_str("Value type mismatch")
751 }
752}
753
754#[derive(Clone, Debug, PartialEq)]
755pub struct Values(pub Vec<Value>);
756
757impl Values {
758 pub fn iter(&self) -> impl Iterator<Item = &Value> {
759 self.0.iter()
760 }
761}
762
763pub trait Nullable {
764 fn null() -> Value;
765}
766
767impl Nullable for &str {
768 fn null() -> Value {
769 Value::String(None)
770 }
771}
772
773macro_rules! type_to_value {
774 ( $type: ty, $name: ident, $col_type: expr ) => {
775 impl From<$type> for Value {
776 fn from(x: $type) -> Value {
777 Value::$name(Some(x))
778 }
779 }
780
781 impl Nullable for $type {
782 fn null() -> Value {
783 Value::$name(None)
784 }
785 }
786
787 impl ValueType for $type {
788 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
789 match v {
790 Value::$name(Some(x)) => Ok(x),
791 _ => Err(ValueTypeErr),
792 }
793 }
794
795 fn type_name() -> String {
796 stringify!($type).to_owned()
797 }
798
799 fn array_type() -> ArrayType {
800 ArrayType::$name
801 }
802
803 fn column_type() -> ColumnType {
804 use ColumnType::*;
805 $col_type
806 }
807 }
808 };
809}
810use type_to_value;
811
812type_to_value!(bool, Bool, Boolean);
813type_to_value!(i8, TinyInt, TinyInteger);
814type_to_value!(i16, SmallInt, SmallInteger);
815type_to_value!(i32, Int, Integer);
816type_to_value!(i64, BigInt, BigInteger);
817type_to_value!(u8, TinyUnsigned, TinyUnsigned);
818type_to_value!(u16, SmallUnsigned, SmallUnsigned);
819type_to_value!(u32, Unsigned, Unsigned);
820type_to_value!(u64, BigUnsigned, BigUnsigned);
821type_to_value!(f32, Float, Float);
822type_to_value!(f64, Double, Double);
823type_to_value!(char, Char, Char(None));
824type_to_value!(Vec<u8>, Bytes, VarBinary(StringLen::None));
825type_to_value!(String, String, String(StringLen::None));
826
827#[cfg(any(feature = "with-bigdecimal", feature = "with-jiff"))]
828macro_rules! type_to_box_value {
829 ( $type: ty, $name: ident, $col_type: expr ) => {
830 impl From<$type> for Value {
831 fn from(x: $type) -> Value {
832 Value::$name(Some(Box::new(x)))
833 }
834 }
835
836 impl Nullable for $type {
837 fn null() -> Value {
838 Value::$name(None)
839 }
840 }
841
842 impl ValueType for $type {
843 fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
844 match v {
845 Value::$name(Some(x)) => Ok(*x),
846 _ => Err(ValueTypeErr),
847 }
848 }
849
850 fn type_name() -> String {
851 stringify!($type).to_owned()
852 }
853
854 fn array_type() -> ArrayType {
855 ArrayType::$name
856 }
857
858 fn column_type() -> ColumnType {
859 use ColumnType::*;
860 $col_type
861 }
862 }
863 };
864}
865
866#[cfg(any(feature = "with-bigdecimal", feature = "with-jiff"))]
867use type_to_box_value;