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