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