1use drizzle_core::{Placeholder, SQL, SQLParam, error::DrizzleError};
4
5mod owned;
6pub use owned::OwnedPostgresValue;
7
8#[cfg(feature = "uuid")]
9use uuid::Uuid;
10
11#[cfg(feature = "chrono")]
12use chrono::{DateTime, Duration, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime, Utc};
13
14#[cfg(feature = "rust_decimal")]
15use rust_decimal::Decimal;
16
17#[cfg(feature = "ipnet")]
18use ipnet::{IpNet, Ipv4Net, Ipv6Net};
19
20#[cfg(feature = "geo-types")]
21use geo_types::{LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon};
22
23#[cfg(feature = "bitvec")]
24use bitvec::prelude::*;
25
26use std::borrow::Cow;
27use std::marker::PhantomData;
28
29use crate::{PostgresEnum, ToPostgresSQL};
30
31#[derive(Debug, Clone)]
37pub struct ValueWrapper<'a, V: SQLParam, T> {
38 pub value: SQL<'a, V>,
39 pub _phantom: PhantomData<T>,
40}
41
42impl<'a, V: SQLParam, T> ValueWrapper<'a, V, T> {
43 pub const fn new<U>(value: SQL<'a, V>) -> ValueWrapper<'a, V, U> {
44 ValueWrapper {
45 value,
46 _phantom: PhantomData,
47 }
48 }
49}
50
51#[derive(Debug, Clone, Default)]
53pub enum PostgresInsertValue<'a, V: SQLParam, T> {
54 #[default]
56 Omit,
57 Null,
59 Value(ValueWrapper<'a, V, T>),
61}
62
63impl<'a, T> PostgresInsertValue<'a, PostgresValue<'a>, T> {
64 pub fn into_owned(self) -> PostgresInsertValue<'static, PostgresValue<'static>, T> {
66 match self {
67 PostgresInsertValue::Omit => PostgresInsertValue::Omit,
68 PostgresInsertValue::Null => PostgresInsertValue::Null,
69 PostgresInsertValue::Value(wrapper) => {
70 if let Some(drizzle_core::SQLChunk::Param(param)) = wrapper.value.chunks.first() {
72 if let Some(ref postgres_val) = param.value {
73 let postgres_val = postgres_val.as_ref();
74 let owned_postgres_val = OwnedPostgresValue::from(postgres_val.clone());
75 let static_postgres_val = PostgresValue::from(owned_postgres_val);
76 let static_sql = drizzle_core::SQL::param(static_postgres_val);
77 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'static>, T>::new(
78 static_sql,
79 ))
80 } else {
81 let static_sql = drizzle_core::SQL::param(PostgresValue::Null);
83 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'static>, T>::new(
84 static_sql,
85 ))
86 }
87 } else {
88 let static_sql = drizzle_core::SQL::param(PostgresValue::Null);
90 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'static>, T>::new(
91 static_sql,
92 ))
93 }
94 }
95 }
96 }
97}
98
99impl<'a, T> From<T> for PostgresInsertValue<'a, PostgresValue<'a>, T>
103where
104 T: TryInto<PostgresValue<'a>>,
105{
106 fn from(value: T) -> Self {
107 let sql = value
108 .try_into()
109 .map(|v: PostgresValue<'a>| SQL::from(v))
110 .unwrap_or_else(|_| SQL::from(PostgresValue::Null));
111 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, T>::new(sql))
112 }
113}
114
115impl<'a> From<&str> for PostgresInsertValue<'a, PostgresValue<'a>, String> {
117 fn from(value: &str) -> Self {
118 let postgres_value = SQL::param(Cow::Owned(PostgresValue::from(value.to_string())));
119 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, String>::new(
120 postgres_value,
121 ))
122 }
123}
124
125impl<'a, T> From<Placeholder> for PostgresInsertValue<'a, PostgresValue<'a>, T> {
127 fn from(placeholder: Placeholder) -> Self {
128 use drizzle_core::{Param, SQLChunk};
129 let chunk = SQLChunk::Param(Param {
130 placeholder,
131 value: None,
132 });
133 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, T>::new(
134 std::iter::once(chunk).collect(),
135 ))
136 }
137}
138
139impl<'a, T> From<Option<T>> for PostgresInsertValue<'a, PostgresValue<'a>, T>
141where
142 T: ToPostgresSQL<'a>,
143{
144 fn from(value: Option<T>) -> Self {
145 match value {
146 Some(v) => {
147 let sql = v.to_sql();
148 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, T>::new(sql))
149 }
150 None => PostgresInsertValue::Omit,
151 }
152 }
153}
154
155#[cfg(feature = "uuid")]
157impl<'a> From<Uuid> for PostgresInsertValue<'a, PostgresValue<'a>, String> {
158 fn from(value: Uuid) -> Self {
159 let postgres_value = PostgresValue::Uuid(value);
160 let sql = SQL::param(postgres_value);
161 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, String>::new(sql))
162 }
163}
164
165#[cfg(feature = "uuid")]
166impl<'a> From<&'a Uuid> for PostgresInsertValue<'a, PostgresValue<'a>, String> {
167 fn from(value: &'a Uuid) -> Self {
168 let postgres_value = PostgresValue::Uuid(*value);
169 let sql = SQL::param(postgres_value);
170 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, String>::new(sql))
171 }
172}
173
174#[derive(Debug, Clone, PartialEq)]
180pub enum PostgresValue<'a> {
181 Smallint(i16),
183 Integer(i32),
185 Bigint(i64),
187 Real(f32),
189 DoublePrecision(f64),
191 Text(Cow<'a, str>),
193 Bytea(Cow<'a, [u8]>),
195 Boolean(bool),
197 #[cfg(feature = "uuid")]
199 Uuid(Uuid),
200 #[cfg(feature = "serde")]
202 Json(serde_json::Value),
203 Enum(Box<dyn PostgresEnum>),
205
206 #[cfg(feature = "chrono")]
209 Date(NaiveDate),
210 #[cfg(feature = "chrono")]
212 Time(NaiveTime),
213 #[cfg(feature = "chrono")]
215 Timestamp(NaiveDateTime),
216 #[cfg(feature = "chrono")]
218 TimestampTz(DateTime<FixedOffset>),
219 #[cfg(feature = "chrono")]
221 Interval(Duration),
222
223 #[cfg(feature = "rust_decimal")]
226 Decimal(Decimal),
227
228 #[cfg(feature = "ipnet")]
231 Inet(IpNet),
232 #[cfg(feature = "ipnet")]
234 Cidr(IpNet),
235 #[cfg(feature = "ipnet")]
237 MacAddr([u8; 6]),
238 #[cfg(feature = "ipnet")]
240 MacAddr8([u8; 8]),
241
242 #[cfg(feature = "geo-types")]
245 Point(Point<f64>),
246 #[cfg(feature = "geo-types")]
248 LineString(LineString<f64>),
249 #[cfg(feature = "geo-types")]
251 Polygon(Polygon<f64>),
252 #[cfg(feature = "geo-types")]
254 MultiPoint(MultiPoint<f64>),
255 #[cfg(feature = "geo-types")]
257 MultiLineString(MultiLineString<f64>),
258 #[cfg(feature = "geo-types")]
260 MultiPolygon(MultiPolygon<f64>),
261
262 #[cfg(feature = "bitvec")]
265 BitVec(BitVec),
266
267 Array(Vec<PostgresValue<'a>>),
270
271 Null,
273}
274
275impl<'a> Default for PostgresValue<'a> {
276 fn default() -> Self {
277 PostgresValue::Null
278 }
279}
280
281impl<'a> std::fmt::Display for PostgresValue<'a> {
282 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
283 let value = match self {
284 PostgresValue::Smallint(i) => i.to_string(),
285 PostgresValue::Integer(i) => i.to_string(),
286 PostgresValue::Bigint(i) => i.to_string(),
287 PostgresValue::Real(r) => r.to_string(),
288 PostgresValue::DoublePrecision(r) => r.to_string(),
289 PostgresValue::Text(cow) => cow.to_string(),
290 PostgresValue::Bytea(cow) => format!(
291 "\\x{}",
292 cow.iter().map(|b| format!("{:02x}", b)).collect::<String>()
293 ),
294 PostgresValue::Boolean(b) => b.to_string(),
295 #[cfg(feature = "uuid")]
296 PostgresValue::Uuid(uuid) => uuid.to_string(),
297 #[cfg(feature = "serde")]
298 PostgresValue::Json(json) => json.to_string(),
299 PostgresValue::Enum(enum_val) => enum_val.variant_name().to_string(),
300
301 #[cfg(feature = "chrono")]
303 PostgresValue::Date(date) => date.format("%Y-%m-%d").to_string(),
304 #[cfg(feature = "chrono")]
305 PostgresValue::Time(time) => time.format("%H:%M:%S%.f").to_string(),
306 #[cfg(feature = "chrono")]
307 PostgresValue::Timestamp(ts) => ts.format("%Y-%m-%d %H:%M:%S%.f").to_string(),
308 #[cfg(feature = "chrono")]
309 PostgresValue::TimestampTz(ts) => ts.format("%Y-%m-%d %H:%M:%S%.f %:z").to_string(),
310 #[cfg(feature = "chrono")]
311 PostgresValue::Interval(dur) => format!("{} seconds", dur.num_seconds()),
312
313 #[cfg(feature = "rust_decimal")]
315 PostgresValue::Decimal(dec) => dec.to_string(),
316
317 #[cfg(feature = "ipnet")]
319 PostgresValue::Inet(net) => net.to_string(),
320 #[cfg(feature = "ipnet")]
321 PostgresValue::Cidr(net) => net.to_string(),
322 #[cfg(feature = "ipnet")]
323 PostgresValue::MacAddr(mac) => format!(
324 "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
325 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
326 ),
327 #[cfg(feature = "ipnet")]
328 PostgresValue::MacAddr8(mac) => format!(
329 "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
330 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mac[6], mac[7]
331 ),
332
333 #[cfg(feature = "geo-types")]
335 PostgresValue::Point(point) => format!("({},{})", point.x(), point.y()),
336 #[cfg(feature = "geo-types")]
337 PostgresValue::LineString(line) => {
338 let coords: Vec<String> = line
339 .coords()
340 .map(|coord| format!("({},{})", coord.x, coord.y))
341 .collect();
342 format!("[{}]", coords.join(","))
343 }
344 #[cfg(feature = "geo-types")]
345 PostgresValue::Polygon(poly) => format!(
346 "POLYGON({})",
347 poly.exterior()
348 .coords()
349 .map(|c| format!("({},{})", c.x, c.y))
350 .collect::<Vec<_>>()
351 .join(",")
352 ),
353 #[cfg(feature = "geo-types")]
354 PostgresValue::MultiPoint(mp) => format!(
355 "MULTIPOINT({})",
356 mp.iter()
357 .map(|p| format!("({},{})", p.x(), p.y()))
358 .collect::<Vec<_>>()
359 .join(",")
360 ),
361 #[cfg(feature = "geo-types")]
362 PostgresValue::MultiLineString(mls) => format!(
363 "MULTILINESTRING({})",
364 mls.iter()
365 .map(|ls| format!(
366 "[{}]",
367 ls.coords()
368 .map(|c| format!("({},{})", c.x, c.y))
369 .collect::<Vec<_>>()
370 .join(",")
371 ))
372 .collect::<Vec<_>>()
373 .join(",")
374 ),
375 #[cfg(feature = "geo-types")]
376 PostgresValue::MultiPolygon(mp) => format!(
377 "MULTIPOLYGON({})",
378 mp.iter()
379 .map(|p| format!(
380 "POLYGON({})",
381 p.exterior()
382 .coords()
383 .map(|c| format!("({},{})", c.x, c.y))
384 .collect::<Vec<_>>()
385 .join(",")
386 ))
387 .collect::<Vec<_>>()
388 .join(",")
389 ),
390
391 #[cfg(feature = "bitvec")]
393 PostgresValue::BitVec(bv) => bv
394 .iter()
395 .map(|b| if *b { '1' } else { '0' })
396 .collect::<String>(),
397
398 PostgresValue::Array(arr) => {
400 let elements: Vec<String> = arr.iter().map(|v| v.to_string()).collect();
401 format!("{{{}}}", elements.join(","))
402 }
403
404 PostgresValue::Null => String::new(),
405 };
406 write!(f, "{value}")
407 }
408}
409
410impl<'a> From<SQL<'a, PostgresValue<'a>>> for PostgresValue<'a> {
411 fn from(_value: SQL<'a, PostgresValue<'a>>) -> Self {
412 unimplemented!()
413 }
414}
415
416impl<'a> SQLParam for PostgresValue<'a> {}
418
419impl<'a> From<PostgresValue<'a>> for SQL<'a, PostgresValue<'a>> {
420 fn from(value: PostgresValue<'a>) -> Self {
421 SQL::param(value)
422 }
423}
424
425impl<'a> From<i8> for PostgresValue<'a> {
433 fn from(value: i8) -> Self {
434 PostgresValue::Smallint(value as i16)
435 }
436}
437
438impl<'a> From<&'a i8> for PostgresValue<'a> {
439 fn from(value: &'a i8) -> Self {
440 PostgresValue::Smallint(*value as i16)
441 }
442}
443
444impl<'a> From<i16> for PostgresValue<'a> {
446 fn from(value: i16) -> Self {
447 PostgresValue::Smallint(value)
448 }
449}
450
451impl<'a> From<&'a i16> for PostgresValue<'a> {
452 fn from(value: &'a i16) -> Self {
453 PostgresValue::Smallint(*value)
454 }
455}
456
457impl<'a> From<i32> for PostgresValue<'a> {
459 fn from(value: i32) -> Self {
460 PostgresValue::Integer(value)
461 }
462}
463
464impl<'a> From<&'a i32> for PostgresValue<'a> {
465 fn from(value: &'a i32) -> Self {
466 PostgresValue::Integer(*value)
467 }
468}
469
470impl<'a> From<i64> for PostgresValue<'a> {
472 fn from(value: i64) -> Self {
473 PostgresValue::Bigint(value)
474 }
475}
476
477impl<'a> From<&'a i64> for PostgresValue<'a> {
478 fn from(value: &'a i64) -> Self {
479 PostgresValue::Bigint(*value)
480 }
481}
482
483impl<'a> From<u8> for PostgresValue<'a> {
485 fn from(value: u8) -> Self {
486 PostgresValue::Smallint(value as i16)
487 }
488}
489
490impl<'a> From<&'a u8> for PostgresValue<'a> {
491 fn from(value: &'a u8) -> Self {
492 PostgresValue::Smallint(*value as i16)
493 }
494}
495
496impl<'a> From<u16> for PostgresValue<'a> {
498 fn from(value: u16) -> Self {
499 PostgresValue::Integer(value as i32)
500 }
501}
502
503impl<'a> From<&'a u16> for PostgresValue<'a> {
504 fn from(value: &'a u16) -> Self {
505 PostgresValue::Integer(*value as i32)
506 }
507}
508
509impl<'a> From<u32> for PostgresValue<'a> {
511 fn from(value: u32) -> Self {
512 PostgresValue::Bigint(value as i64)
513 }
514}
515
516impl<'a> From<&'a u32> for PostgresValue<'a> {
517 fn from(value: &'a u32) -> Self {
518 PostgresValue::Bigint(*value as i64)
519 }
520}
521
522impl<'a> From<u64> for PostgresValue<'a> {
524 fn from(value: u64) -> Self {
525 PostgresValue::Bigint(value as i64)
526 }
527}
528
529impl<'a> From<&'a u64> for PostgresValue<'a> {
530 fn from(value: &'a u64) -> Self {
531 PostgresValue::Bigint(*value as i64)
532 }
533}
534
535impl<'a> From<isize> for PostgresValue<'a> {
537 fn from(value: isize) -> Self {
538 PostgresValue::Bigint(value as i64)
539 }
540}
541
542impl<'a> From<&'a isize> for PostgresValue<'a> {
543 fn from(value: &'a isize) -> Self {
544 PostgresValue::Bigint(*value as i64)
545 }
546}
547
548impl<'a> From<usize> for PostgresValue<'a> {
550 fn from(value: usize) -> Self {
551 PostgresValue::Bigint(value as i64)
552 }
553}
554
555impl<'a> From<&'a usize> for PostgresValue<'a> {
556 fn from(value: &'a usize) -> Self {
557 PostgresValue::Bigint(*value as i64)
558 }
559}
560
561impl<'a> From<f32> for PostgresValue<'a> {
565 fn from(value: f32) -> Self {
566 PostgresValue::Real(value)
567 }
568}
569
570impl<'a> From<&'a f32> for PostgresValue<'a> {
571 fn from(value: &'a f32) -> Self {
572 PostgresValue::Real(*value)
573 }
574}
575
576impl<'a> From<f64> for PostgresValue<'a> {
578 fn from(value: f64) -> Self {
579 PostgresValue::DoublePrecision(value)
580 }
581}
582
583impl<'a> From<&'a f64> for PostgresValue<'a> {
584 fn from(value: &'a f64) -> Self {
585 PostgresValue::DoublePrecision(*value)
586 }
587}
588
589impl<'a> From<bool> for PostgresValue<'a> {
592 fn from(value: bool) -> Self {
593 PostgresValue::Boolean(value)
594 }
595}
596
597impl<'a> From<&'a bool> for PostgresValue<'a> {
598 fn from(value: &'a bool) -> Self {
599 PostgresValue::Boolean(*value)
600 }
601}
602
603impl<'a> From<&'a str> for PostgresValue<'a> {
606 fn from(value: &'a str) -> Self {
607 PostgresValue::Text(Cow::Borrowed(value))
608 }
609}
610
611impl<'a> From<String> for PostgresValue<'a> {
612 fn from(value: String) -> Self {
613 PostgresValue::Text(Cow::Owned(value))
614 }
615}
616
617impl<'a> From<&'a String> for PostgresValue<'a> {
618 fn from(value: &'a String) -> Self {
619 PostgresValue::Text(Cow::Borrowed(value))
620 }
621}
622
623impl<'a> From<&'a [u8]> for PostgresValue<'a> {
626 fn from(value: &'a [u8]) -> Self {
627 PostgresValue::Bytea(Cow::Borrowed(value))
628 }
629}
630
631impl<'a> From<Vec<u8>> for PostgresValue<'a> {
632 fn from(value: Vec<u8>) -> Self {
633 PostgresValue::Bytea(Cow::Owned(value))
634 }
635}
636
637#[cfg(feature = "uuid")]
640impl<'a> From<Uuid> for PostgresValue<'a> {
641 fn from(value: Uuid) -> Self {
642 PostgresValue::Uuid(value)
643 }
644}
645
646#[cfg(feature = "uuid")]
647impl<'a> From<&'a Uuid> for PostgresValue<'a> {
648 fn from(value: &'a Uuid) -> Self {
649 PostgresValue::Uuid(*value)
650 }
651}
652
653#[cfg(feature = "serde")]
656impl<'a> From<serde_json::Value> for PostgresValue<'a> {
657 fn from(value: serde_json::Value) -> Self {
658 PostgresValue::Json(value)
659 }
660}
661
662#[cfg(feature = "serde")]
663impl<'a> From<&'a serde_json::Value> for PostgresValue<'a> {
664 fn from(value: &'a serde_json::Value) -> Self {
665 PostgresValue::Json(value.clone())
666 }
667}
668
669#[cfg(feature = "chrono")]
672impl<'a> From<NaiveDate> for PostgresValue<'a> {
673 fn from(value: NaiveDate) -> Self {
674 PostgresValue::Date(value)
675 }
676}
677
678#[cfg(feature = "chrono")]
679impl<'a> From<&'a NaiveDate> for PostgresValue<'a> {
680 fn from(value: &'a NaiveDate) -> Self {
681 PostgresValue::Date(*value)
682 }
683}
684
685#[cfg(feature = "chrono")]
686impl<'a> From<NaiveTime> for PostgresValue<'a> {
687 fn from(value: NaiveTime) -> Self {
688 PostgresValue::Time(value)
689 }
690}
691
692#[cfg(feature = "chrono")]
693impl<'a> From<&'a NaiveTime> for PostgresValue<'a> {
694 fn from(value: &'a NaiveTime) -> Self {
695 PostgresValue::Time(*value)
696 }
697}
698
699#[cfg(feature = "chrono")]
700impl<'a> From<NaiveDateTime> for PostgresValue<'a> {
701 fn from(value: NaiveDateTime) -> Self {
702 PostgresValue::Timestamp(value)
703 }
704}
705
706#[cfg(feature = "chrono")]
707impl<'a> From<&'a NaiveDateTime> for PostgresValue<'a> {
708 fn from(value: &'a NaiveDateTime) -> Self {
709 PostgresValue::Timestamp(*value)
710 }
711}
712
713#[cfg(feature = "chrono")]
714impl<'a> From<DateTime<FixedOffset>> for PostgresValue<'a> {
715 fn from(value: DateTime<FixedOffset>) -> Self {
716 PostgresValue::TimestampTz(value)
717 }
718}
719
720#[cfg(feature = "chrono")]
721impl<'a> From<&'a DateTime<FixedOffset>> for PostgresValue<'a> {
722 fn from(value: &'a DateTime<FixedOffset>) -> Self {
723 PostgresValue::TimestampTz(*value)
724 }
725}
726
727#[cfg(feature = "chrono")]
728impl<'a> From<DateTime<Utc>> for PostgresValue<'a> {
729 fn from(value: DateTime<Utc>) -> Self {
730 PostgresValue::TimestampTz(value.into())
731 }
732}
733
734#[cfg(feature = "chrono")]
735impl<'a> From<&'a DateTime<Utc>> for PostgresValue<'a> {
736 fn from(value: &'a DateTime<Utc>) -> Self {
737 PostgresValue::TimestampTz((*value).into())
738 }
739}
740
741#[cfg(feature = "chrono")]
742impl<'a> From<Duration> for PostgresValue<'a> {
743 fn from(value: Duration) -> Self {
744 PostgresValue::Interval(value)
745 }
746}
747
748#[cfg(feature = "chrono")]
749impl<'a> From<&'a Duration> for PostgresValue<'a> {
750 fn from(value: &'a Duration) -> Self {
751 PostgresValue::Interval(*value)
752 }
753}
754
755#[cfg(feature = "rust_decimal")]
758impl<'a> From<Decimal> for PostgresValue<'a> {
759 fn from(value: Decimal) -> Self {
760 PostgresValue::Decimal(value)
761 }
762}
763
764#[cfg(feature = "rust_decimal")]
765impl<'a> From<&'a Decimal> for PostgresValue<'a> {
766 fn from(value: &'a Decimal) -> Self {
767 PostgresValue::Decimal(*value)
768 }
769}
770
771#[cfg(feature = "ipnet")]
774impl<'a> From<IpNet> for PostgresValue<'a> {
775 fn from(value: IpNet) -> Self {
776 PostgresValue::Inet(value)
777 }
778}
779
780#[cfg(feature = "ipnet")]
781impl<'a> From<&'a IpNet> for PostgresValue<'a> {
782 fn from(value: &'a IpNet) -> Self {
783 PostgresValue::Inet(*value)
784 }
785}
786
787#[cfg(feature = "ipnet")]
788impl<'a> From<Ipv4Net> for PostgresValue<'a> {
789 fn from(value: Ipv4Net) -> Self {
790 PostgresValue::Inet(value.into())
791 }
792}
793
794#[cfg(feature = "ipnet")]
795impl<'a> From<Ipv6Net> for PostgresValue<'a> {
796 fn from(value: Ipv6Net) -> Self {
797 PostgresValue::Inet(value.into())
798 }
799}
800
801#[cfg(feature = "ipnet")]
802impl<'a> From<[u8; 6]> for PostgresValue<'a> {
803 fn from(value: [u8; 6]) -> Self {
804 PostgresValue::MacAddr(value)
805 }
806}
807
808#[cfg(feature = "ipnet")]
809impl<'a> From<&'a [u8; 6]> for PostgresValue<'a> {
810 fn from(value: &'a [u8; 6]) -> Self {
811 PostgresValue::MacAddr(*value)
812 }
813}
814
815#[cfg(feature = "ipnet")]
816impl<'a> From<[u8; 8]> for PostgresValue<'a> {
817 fn from(value: [u8; 8]) -> Self {
818 PostgresValue::MacAddr8(value)
819 }
820}
821
822#[cfg(feature = "ipnet")]
823impl<'a> From<&'a [u8; 8]> for PostgresValue<'a> {
824 fn from(value: &'a [u8; 8]) -> Self {
825 PostgresValue::MacAddr8(*value)
826 }
827}
828
829#[cfg(feature = "geo-types")]
832impl<'a> From<Point<f64>> for PostgresValue<'a> {
833 fn from(value: Point<f64>) -> Self {
834 PostgresValue::Point(value)
835 }
836}
837
838#[cfg(feature = "geo-types")]
839impl<'a> From<&'a Point<f64>> for PostgresValue<'a> {
840 fn from(value: &'a Point<f64>) -> Self {
841 PostgresValue::Point(*value)
842 }
843}
844
845#[cfg(feature = "geo-types")]
846impl<'a> From<LineString<f64>> for PostgresValue<'a> {
847 fn from(value: LineString<f64>) -> Self {
848 PostgresValue::LineString(value)
849 }
850}
851
852#[cfg(feature = "geo-types")]
853impl<'a> From<&'a LineString<f64>> for PostgresValue<'a> {
854 fn from(value: &'a LineString<f64>) -> Self {
855 PostgresValue::LineString(value.clone())
856 }
857}
858
859#[cfg(feature = "geo-types")]
860impl<'a> From<Polygon<f64>> for PostgresValue<'a> {
861 fn from(value: Polygon<f64>) -> Self {
862 PostgresValue::Polygon(value)
863 }
864}
865
866#[cfg(feature = "geo-types")]
867impl<'a> From<&'a Polygon<f64>> for PostgresValue<'a> {
868 fn from(value: &'a Polygon<f64>) -> Self {
869 PostgresValue::Polygon(value.clone())
870 }
871}
872
873#[cfg(feature = "geo-types")]
874impl<'a> From<MultiPoint<f64>> for PostgresValue<'a> {
875 fn from(value: MultiPoint<f64>) -> Self {
876 PostgresValue::MultiPoint(value)
877 }
878}
879
880#[cfg(feature = "geo-types")]
881impl<'a> From<&'a MultiPoint<f64>> for PostgresValue<'a> {
882 fn from(value: &'a MultiPoint<f64>) -> Self {
883 PostgresValue::MultiPoint(value.clone())
884 }
885}
886
887#[cfg(feature = "geo-types")]
888impl<'a> From<MultiLineString<f64>> for PostgresValue<'a> {
889 fn from(value: MultiLineString<f64>) -> Self {
890 PostgresValue::MultiLineString(value)
891 }
892}
893
894#[cfg(feature = "geo-types")]
895impl<'a> From<&'a MultiLineString<f64>> for PostgresValue<'a> {
896 fn from(value: &'a MultiLineString<f64>) -> Self {
897 PostgresValue::MultiLineString(value.clone())
898 }
899}
900
901#[cfg(feature = "geo-types")]
902impl<'a> From<MultiPolygon<f64>> for PostgresValue<'a> {
903 fn from(value: MultiPolygon<f64>) -> Self {
904 PostgresValue::MultiPolygon(value)
905 }
906}
907
908#[cfg(feature = "geo-types")]
909impl<'a> From<&'a MultiPolygon<f64>> for PostgresValue<'a> {
910 fn from(value: &'a MultiPolygon<f64>) -> Self {
911 PostgresValue::MultiPolygon(value.clone())
912 }
913}
914
915#[cfg(feature = "bitvec")]
918impl<'a> From<BitVec> for PostgresValue<'a> {
919 fn from(value: BitVec) -> Self {
920 PostgresValue::BitVec(value)
921 }
922}
923
924#[cfg(feature = "bitvec")]
925impl<'a> From<&'a BitVec> for PostgresValue<'a> {
926 fn from(value: &'a BitVec) -> Self {
927 PostgresValue::BitVec(value.clone())
928 }
929}
930
931impl<'a> From<Vec<PostgresValue<'a>>> for PostgresValue<'a> {
934 fn from(value: Vec<PostgresValue<'a>>) -> Self {
935 PostgresValue::Array(value)
936 }
937}
938
939impl<'a> From<&'a [PostgresValue<'a>]> for PostgresValue<'a> {
940 fn from(value: &'a [PostgresValue<'a>]) -> Self {
941 PostgresValue::Array(value.to_vec())
942 }
943}
944
945impl<'a, T> From<Option<T>> for PostgresValue<'a>
947where
948 T: TryInto<PostgresValue<'a>>,
949{
950 fn from(value: Option<T>) -> Self {
951 match value {
952 Some(value) => value.try_into().unwrap_or(PostgresValue::Null),
953 None => PostgresValue::Null,
954 }
955 }
956}
957
958impl<'a> From<PostgresValue<'a>> for Cow<'a, PostgresValue<'a>> {
960 fn from(value: PostgresValue<'a>) -> Self {
961 Cow::Owned(value)
962 }
963}
964
965impl<'a> From<&'a PostgresValue<'a>> for Cow<'a, PostgresValue<'a>> {
966 fn from(value: &'a PostgresValue<'a>) -> Self {
967 Cow::Borrowed(value)
968 }
969}
970
971impl<'a> TryFrom<PostgresValue<'a>> for i16 {
978 type Error = DrizzleError;
979
980 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
981 match value {
982 PostgresValue::Smallint(i) => Ok(i),
983 PostgresValue::Integer(i) => Ok(i.try_into()?),
984 PostgresValue::Bigint(i) => Ok(i.try_into()?),
985 _ => Err(DrizzleError::ConversionError(
986 format!("Cannot convert {:?} to i16", value).into(),
987 )),
988 }
989 }
990}
991
992impl<'a> TryFrom<PostgresValue<'a>> for i32 {
993 type Error = DrizzleError;
994
995 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
996 match value {
997 PostgresValue::Smallint(i) => Ok(i.into()),
998 PostgresValue::Integer(i) => Ok(i),
999 PostgresValue::Bigint(i) => Ok(i.try_into()?),
1000 _ => Err(DrizzleError::ConversionError(
1001 format!("Cannot convert {:?} to i32", value).into(),
1002 )),
1003 }
1004 }
1005}
1006
1007impl<'a> TryFrom<PostgresValue<'a>> for i64 {
1008 type Error = DrizzleError;
1009
1010 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1011 match value {
1012 PostgresValue::Smallint(i) => Ok(i.into()),
1013 PostgresValue::Integer(i) => Ok(i.into()),
1014 PostgresValue::Bigint(i) => Ok(i),
1015 _ => Err(DrizzleError::ConversionError(
1016 format!("Cannot convert {:?} to i64", value).into(),
1017 )),
1018 }
1019 }
1020}
1021
1022impl<'a> TryFrom<PostgresValue<'a>> for f32 {
1025 type Error = DrizzleError;
1026
1027 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1028 match value {
1029 PostgresValue::Real(f) => Ok(f),
1030 PostgresValue::DoublePrecision(f) => Ok(f as f32),
1031 PostgresValue::Smallint(i) => Ok(i as f32),
1032 PostgresValue::Integer(i) => Ok(i as f32),
1033 PostgresValue::Bigint(i) => Ok(i as f32),
1034 _ => Err(DrizzleError::ConversionError(
1035 format!("Cannot convert {:?} to f32", value).into(),
1036 )),
1037 }
1038 }
1039}
1040
1041impl<'a> TryFrom<PostgresValue<'a>> for f64 {
1042 type Error = DrizzleError;
1043
1044 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1045 match value {
1046 PostgresValue::Real(f) => Ok(f as f64),
1047 PostgresValue::DoublePrecision(f) => Ok(f),
1048 PostgresValue::Smallint(i) => Ok(i as f64),
1049 PostgresValue::Integer(i) => Ok(i as f64),
1050 PostgresValue::Bigint(i) => Ok(i as f64),
1051 _ => Err(DrizzleError::ConversionError(
1052 format!("Cannot convert {:?} to f64", value).into(),
1053 )),
1054 }
1055 }
1056}
1057
1058impl<'a> TryFrom<PostgresValue<'a>> for bool {
1061 type Error = DrizzleError;
1062
1063 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1064 match value {
1065 PostgresValue::Boolean(b) => Ok(b),
1066 _ => Err(DrizzleError::ConversionError(
1067 format!("Cannot convert {:?} to bool", value).into(),
1068 )),
1069 }
1070 }
1071}
1072
1073impl<'a> TryFrom<PostgresValue<'a>> for String {
1076 type Error = DrizzleError;
1077
1078 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1079 match value {
1080 PostgresValue::Text(cow) => Ok(cow.into_owned()),
1081 _ => Err(DrizzleError::ConversionError(
1082 format!("Cannot convert {:?} to String", value).into(),
1083 )),
1084 }
1085 }
1086}
1087
1088impl<'a> TryFrom<PostgresValue<'a>> for Vec<u8> {
1091 type Error = DrizzleError;
1092
1093 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1094 match value {
1095 PostgresValue::Bytea(cow) => Ok(cow.into_owned()),
1096 _ => Err(DrizzleError::ConversionError(
1097 format!("Cannot convert {:?} to Vec<u8>", value).into(),
1098 )),
1099 }
1100 }
1101}
1102
1103#[cfg(feature = "uuid")]
1106impl<'a> TryFrom<PostgresValue<'a>> for Uuid {
1107 type Error = DrizzleError;
1108
1109 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1110 match value {
1111 PostgresValue::Uuid(uuid) => Ok(uuid),
1112 PostgresValue::Text(cow) => Ok(Uuid::parse_str(cow.as_ref())?),
1113 _ => Err(DrizzleError::ConversionError(
1114 format!("Cannot convert {:?} to UUID", value).into(),
1115 )),
1116 }
1117 }
1118}
1119
1120#[cfg(feature = "serde")]
1123impl<'a> TryFrom<PostgresValue<'a>> for serde_json::Value {
1124 type Error = DrizzleError;
1125
1126 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1127 match value {
1128 PostgresValue::Json(json) => Ok(json),
1129 PostgresValue::Text(cow) => serde_json::from_str(cow.as_ref()).map_err(|e| {
1130 DrizzleError::ConversionError(format!("Failed to parse JSON: {}", e).into())
1131 }),
1132 _ => Err(DrizzleError::ConversionError(
1133 format!("Cannot convert {:?} to JSON", value).into(),
1134 )),
1135 }
1136 }
1137}
1138
1139#[cfg(feature = "chrono")]
1142impl<'a> TryFrom<PostgresValue<'a>> for NaiveDate {
1143 type Error = DrizzleError;
1144
1145 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1146 match value {
1147 PostgresValue::Date(date) => Ok(date),
1148 PostgresValue::Timestamp(ts) => Ok(ts.date()),
1149 PostgresValue::TimestampTz(ts) => Ok(ts.date_naive()),
1150 _ => Err(DrizzleError::ConversionError(
1151 format!("Cannot convert {:?} to NaiveDate", value).into(),
1152 )),
1153 }
1154 }
1155}
1156
1157#[cfg(feature = "chrono")]
1158impl<'a> TryFrom<PostgresValue<'a>> for NaiveTime {
1159 type Error = DrizzleError;
1160
1161 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1162 match value {
1163 PostgresValue::Time(time) => Ok(time),
1164 PostgresValue::Timestamp(ts) => Ok(ts.time()),
1165 PostgresValue::TimestampTz(ts) => Ok(ts.time()),
1166 _ => Err(DrizzleError::ConversionError(
1167 format!("Cannot convert {:?} to NaiveTime", value).into(),
1168 )),
1169 }
1170 }
1171}
1172
1173#[cfg(feature = "chrono")]
1174impl<'a> TryFrom<PostgresValue<'a>> for NaiveDateTime {
1175 type Error = DrizzleError;
1176
1177 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1178 match value {
1179 PostgresValue::Timestamp(ts) => Ok(ts),
1180 PostgresValue::TimestampTz(ts) => Ok(ts.naive_utc()),
1181 _ => Err(DrizzleError::ConversionError(
1182 format!("Cannot convert {:?} to NaiveDateTime", value).into(),
1183 )),
1184 }
1185 }
1186}
1187
1188#[cfg(feature = "chrono")]
1189impl<'a> TryFrom<PostgresValue<'a>> for DateTime<FixedOffset> {
1190 type Error = DrizzleError;
1191
1192 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1193 match value {
1194 PostgresValue::TimestampTz(ts) => Ok(ts),
1195 _ => Err(DrizzleError::ConversionError(
1196 format!("Cannot convert {:?} to DateTime<FixedOffset>", value).into(),
1197 )),
1198 }
1199 }
1200}
1201
1202#[cfg(feature = "chrono")]
1203impl<'a> TryFrom<PostgresValue<'a>> for DateTime<Utc> {
1204 type Error = DrizzleError;
1205
1206 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1207 match value {
1208 PostgresValue::TimestampTz(ts) => Ok(ts.with_timezone(&Utc)),
1209 _ => Err(DrizzleError::ConversionError(
1210 format!("Cannot convert {:?} to DateTime<Utc>", value).into(),
1211 )),
1212 }
1213 }
1214}
1215
1216#[cfg(feature = "chrono")]
1217impl<'a> TryFrom<PostgresValue<'a>> for Duration {
1218 type Error = DrizzleError;
1219
1220 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1221 match value {
1222 PostgresValue::Interval(duration) => Ok(duration),
1223 _ => Err(DrizzleError::ConversionError(
1224 format!("Cannot convert {:?} to Duration", value).into(),
1225 )),
1226 }
1227 }
1228}
1229
1230#[cfg(feature = "rust_decimal")]
1233impl<'a> TryFrom<PostgresValue<'a>> for Decimal {
1234 type Error = DrizzleError;
1235
1236 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1237 match value {
1238 PostgresValue::Decimal(dec) => Ok(dec),
1239 PostgresValue::Smallint(i) => Ok(Decimal::from(i)),
1240 PostgresValue::Integer(i) => Ok(Decimal::from(i)),
1241 PostgresValue::Bigint(i) => Ok(Decimal::from(i)),
1242 PostgresValue::Real(f) => Decimal::try_from(f).map_err(|e| {
1243 DrizzleError::ConversionError(
1244 format!("Failed to convert float to decimal: {}", e).into(),
1245 )
1246 }),
1247 PostgresValue::DoublePrecision(f) => Decimal::try_from(f).map_err(|e| {
1248 DrizzleError::ConversionError(
1249 format!("Failed to convert float to decimal: {}", e).into(),
1250 )
1251 }),
1252 _ => Err(DrizzleError::ConversionError(
1253 format!("Cannot convert {:?} to Decimal", value).into(),
1254 )),
1255 }
1256 }
1257}
1258
1259#[cfg(feature = "ipnet")]
1262impl<'a> TryFrom<PostgresValue<'a>> for IpNet {
1263 type Error = DrizzleError;
1264
1265 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1266 match value {
1267 PostgresValue::Inet(net) => Ok(net),
1268 PostgresValue::Cidr(net) => Ok(net),
1269 _ => Err(DrizzleError::ConversionError(
1270 format!("Cannot convert {:?} to IpNet", value).into(),
1271 )),
1272 }
1273 }
1274}
1275
1276#[cfg(feature = "ipnet")]
1277impl<'a> TryFrom<PostgresValue<'a>> for [u8; 6] {
1278 type Error = DrizzleError;
1279
1280 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1281 match value {
1282 PostgresValue::MacAddr(mac) => Ok(mac),
1283 _ => Err(DrizzleError::ConversionError(
1284 format!("Cannot convert {:?} to [u8; 6]", value).into(),
1285 )),
1286 }
1287 }
1288}
1289
1290#[cfg(feature = "ipnet")]
1291impl<'a> TryFrom<PostgresValue<'a>> for [u8; 8] {
1292 type Error = DrizzleError;
1293
1294 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1295 match value {
1296 PostgresValue::MacAddr8(mac) => Ok(mac),
1297 _ => Err(DrizzleError::ConversionError(
1298 format!("Cannot convert {:?} to [u8; 8]", value).into(),
1299 )),
1300 }
1301 }
1302}
1303
1304#[cfg(feature = "geo-types")]
1307impl<'a> TryFrom<PostgresValue<'a>> for Point<f64> {
1308 type Error = DrizzleError;
1309
1310 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1311 match value {
1312 PostgresValue::Point(point) => Ok(point),
1313 _ => Err(DrizzleError::ConversionError(
1314 format!("Cannot convert {:?} to Point", value).into(),
1315 )),
1316 }
1317 }
1318}
1319
1320#[cfg(feature = "geo-types")]
1321impl<'a> TryFrom<PostgresValue<'a>> for LineString<f64> {
1322 type Error = DrizzleError;
1323
1324 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1325 match value {
1326 PostgresValue::LineString(line) => Ok(line),
1327 _ => Err(DrizzleError::ConversionError(
1328 format!("Cannot convert {:?} to LineString", value).into(),
1329 )),
1330 }
1331 }
1332}
1333
1334#[cfg(feature = "geo-types")]
1335impl<'a> TryFrom<PostgresValue<'a>> for Polygon<f64> {
1336 type Error = DrizzleError;
1337
1338 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1339 match value {
1340 PostgresValue::Polygon(poly) => Ok(poly),
1341 _ => Err(DrizzleError::ConversionError(
1342 format!("Cannot convert {:?} to Polygon", value).into(),
1343 )),
1344 }
1345 }
1346}
1347
1348#[cfg(feature = "geo-types")]
1349impl<'a> TryFrom<PostgresValue<'a>> for MultiPoint<f64> {
1350 type Error = DrizzleError;
1351
1352 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1353 match value {
1354 PostgresValue::MultiPoint(mp) => Ok(mp),
1355 _ => Err(DrizzleError::ConversionError(
1356 format!("Cannot convert {:?} to MultiPoint", value).into(),
1357 )),
1358 }
1359 }
1360}
1361
1362#[cfg(feature = "geo-types")]
1363impl<'a> TryFrom<PostgresValue<'a>> for MultiLineString<f64> {
1364 type Error = DrizzleError;
1365
1366 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1367 match value {
1368 PostgresValue::MultiLineString(mls) => Ok(mls),
1369 _ => Err(DrizzleError::ConversionError(
1370 format!("Cannot convert {:?} to MultiLineString", value).into(),
1371 )),
1372 }
1373 }
1374}
1375
1376#[cfg(feature = "geo-types")]
1377impl<'a> TryFrom<PostgresValue<'a>> for MultiPolygon<f64> {
1378 type Error = DrizzleError;
1379
1380 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1381 match value {
1382 PostgresValue::MultiPolygon(mp) => Ok(mp),
1383 _ => Err(DrizzleError::ConversionError(
1384 format!("Cannot convert {:?} to MultiPolygon", value).into(),
1385 )),
1386 }
1387 }
1388}
1389
1390#[cfg(feature = "bitvec")]
1393impl<'a> TryFrom<PostgresValue<'a>> for BitVec {
1394 type Error = DrizzleError;
1395
1396 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1397 match value {
1398 PostgresValue::BitVec(bv) => Ok(bv),
1399 _ => Err(DrizzleError::ConversionError(
1400 format!("Cannot convert {:?} to BitVec", value).into(),
1401 )),
1402 }
1403 }
1404}
1405
1406impl<'a> TryFrom<PostgresValue<'a>> for Vec<PostgresValue<'a>> {
1409 type Error = DrizzleError;
1410
1411 fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1412 match value {
1413 PostgresValue::Array(arr) => Ok(arr),
1414 _ => Err(DrizzleError::ConversionError(
1415 format!("Cannot convert {:?} to Vec<PostgresValue>", value).into(),
1416 )),
1417 }
1418 }
1419}
1420
1421#[cfg(feature = "sqlx-postgres")]
1427mod sqlx_impls {
1428 use super::*;
1429 use sqlx::{Encode, Postgres, Type, postgres::PgArgumentBuffer};
1430
1431 impl<'a> Type<Postgres> for PostgresValue<'a> {
1432 fn type_info() -> sqlx::postgres::PgTypeInfo {
1433 <String as Type<Postgres>>::type_info()
1435 }
1436 }
1437
1438 impl<'a> Encode<'_, Postgres> for PostgresValue<'a> {
1439 fn encode_by_ref(
1440 &self,
1441 buf: &mut PgArgumentBuffer,
1442 ) -> Result<sqlx::encode::IsNull, Box<dyn std::error::Error + Send + Sync>> {
1443 match self {
1444 PostgresValue::Null => Ok(sqlx::encode::IsNull::Yes),
1445 PostgresValue::Integer(i) => i.encode_by_ref(buf),
1446 PostgresValue::Real(f) => f.encode_by_ref(buf),
1447 PostgresValue::Text(cow) => cow.as_ref().encode_by_ref(buf),
1448 PostgresValue::Bytea(cow) => cow.as_ref().encode_by_ref(buf),
1449 PostgresValue::Boolean(b) => b.encode_by_ref(buf),
1450 #[cfg(feature = "uuid")]
1451 PostgresValue::Uuid(uuid) => uuid.encode_by_ref(buf),
1452 #[cfg(feature = "serde")]
1453 PostgresValue::Json(json) => json.encode_by_ref(buf),
1454 PostgresValue::Enum(enum_val) => enum_val.variant_name().encode_by_ref(buf),
1455 }
1456 }
1457 }
1458}