Skip to main content

drizzle_postgres/values/
conversions.rs

1//! `From<T>` and `TryFrom<PostgresValue>` implementations.
2
3use super::PostgresValue;
4use crate::prelude::*;
5use drizzle_core::error::DrizzleError;
6
7#[cfg(feature = "uuid")]
8use uuid::Uuid;
9
10#[cfg(feature = "chrono")]
11use chrono::{DateTime, Duration, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime, Utc};
12
13#[cfg(feature = "time")]
14use time::{
15    Date as TimeDate, Duration as TimeDuration, OffsetDateTime, PrimitiveDateTime, Time as TimeTime,
16};
17
18#[cfg(feature = "jiff")]
19use jiff::{
20    Timestamp as JiffTimestamp,
21    civil::{Date as JiffDate, DateTime as JiffDateTime, Time as JiffTime},
22};
23
24#[cfg(feature = "cidr")]
25use cidr::{IpCidr, IpInet};
26
27#[cfg(feature = "geo-types")]
28use geo_types::{LineString, Point, Rect};
29
30#[cfg(feature = "bit-vec")]
31use bit_vec::BitVec;
32
33#[cfg(feature = "rust-decimal")]
34use rust_decimal::Decimal;
35
36//------------------------------------------------------------------------------
37// From<T> implementations
38//------------------------------------------------------------------------------
39
40// --- Integer Types ---
41
42// i8 → SMALLINT (PostgreSQL doesn't have a native i8 type)
43impl From<i8> for PostgresValue<'_> {
44    fn from(value: i8) -> Self {
45        PostgresValue::Smallint(i16::from(value))
46    }
47}
48
49impl<'a> From<&'a i8> for PostgresValue<'a> {
50    fn from(value: &'a i8) -> Self {
51        PostgresValue::Smallint(i16::from(*value))
52    }
53}
54
55// i16 (SMALLINT)
56impl From<i16> for PostgresValue<'_> {
57    fn from(value: i16) -> Self {
58        PostgresValue::Smallint(value)
59    }
60}
61
62impl<'a> From<&'a i16> for PostgresValue<'a> {
63    fn from(value: &'a i16) -> Self {
64        PostgresValue::Smallint(*value)
65    }
66}
67
68// i32 (INTEGER)
69impl From<i32> for PostgresValue<'_> {
70    fn from(value: i32) -> Self {
71        PostgresValue::Integer(value)
72    }
73}
74
75impl<'a> From<&'a i32> for PostgresValue<'a> {
76    fn from(value: &'a i32) -> Self {
77        PostgresValue::Integer(*value)
78    }
79}
80
81// i64 (BIGINT)
82impl From<i64> for PostgresValue<'_> {
83    fn from(value: i64) -> Self {
84        PostgresValue::Bigint(value)
85    }
86}
87
88impl<'a> From<&'a i64> for PostgresValue<'a> {
89    fn from(value: &'a i64) -> Self {
90        PostgresValue::Bigint(*value)
91    }
92}
93
94// u8 → SMALLINT (PostgreSQL doesn't have unsigned types)
95impl From<u8> for PostgresValue<'_> {
96    fn from(value: u8) -> Self {
97        PostgresValue::Smallint(i16::from(value))
98    }
99}
100
101impl<'a> From<&'a u8> for PostgresValue<'a> {
102    fn from(value: &'a u8) -> Self {
103        PostgresValue::Smallint(i16::from(*value))
104    }
105}
106
107// u16 → INTEGER (cast to larger signed type)
108impl From<u16> for PostgresValue<'_> {
109    fn from(value: u16) -> Self {
110        PostgresValue::Integer(i32::from(value))
111    }
112}
113
114impl<'a> From<&'a u16> for PostgresValue<'a> {
115    fn from(value: &'a u16) -> Self {
116        PostgresValue::Integer(i32::from(*value))
117    }
118}
119
120// u32 → BIGINT (cast to larger signed type since u32 max > i32 max)
121impl From<u32> for PostgresValue<'_> {
122    fn from(value: u32) -> Self {
123        PostgresValue::Bigint(i64::from(value))
124    }
125}
126
127impl<'a> From<&'a u32> for PostgresValue<'a> {
128    fn from(value: &'a u32) -> Self {
129        PostgresValue::Bigint(i64::from(*value))
130    }
131}
132
133// u64 → BIGINT (saturating to i64::MAX since u64 max > i64 max)
134impl From<u64> for PostgresValue<'_> {
135    fn from(value: u64) -> Self {
136        PostgresValue::Bigint(i64::try_from(value).unwrap_or(i64::MAX))
137    }
138}
139
140impl<'a> From<&'a u64> for PostgresValue<'a> {
141    fn from(value: &'a u64) -> Self {
142        PostgresValue::Bigint(i64::try_from(*value).unwrap_or(i64::MAX))
143    }
144}
145
146// isize → BIGINT (platform-dependent size)
147impl From<isize> for PostgresValue<'_> {
148    fn from(value: isize) -> Self {
149        PostgresValue::Bigint(value as i64)
150    }
151}
152
153impl<'a> From<&'a isize> for PostgresValue<'a> {
154    fn from(value: &'a isize) -> Self {
155        PostgresValue::Bigint(*value as i64)
156    }
157}
158
159// usize → BIGINT (platform-dependent size; saturates to i64::MAX on 64-bit targets)
160impl From<usize> for PostgresValue<'_> {
161    fn from(value: usize) -> Self {
162        PostgresValue::Bigint(i64::try_from(value).unwrap_or(i64::MAX))
163    }
164}
165
166impl<'a> From<&'a usize> for PostgresValue<'a> {
167    fn from(value: &'a usize) -> Self {
168        PostgresValue::Bigint(i64::try_from(*value).unwrap_or(i64::MAX))
169    }
170}
171
172// --- Floating Point Types ---
173
174// f32 (REAL)
175impl From<f32> for PostgresValue<'_> {
176    fn from(value: f32) -> Self {
177        PostgresValue::Real(value)
178    }
179}
180
181impl<'a> From<&'a f32> for PostgresValue<'a> {
182    fn from(value: &'a f32) -> Self {
183        PostgresValue::Real(*value)
184    }
185}
186
187// f64 (DOUBLE PRECISION)
188impl From<f64> for PostgresValue<'_> {
189    fn from(value: f64) -> Self {
190        PostgresValue::DoublePrecision(value)
191    }
192}
193
194impl<'a> From<&'a f64> for PostgresValue<'a> {
195    fn from(value: &'a f64) -> Self {
196        PostgresValue::DoublePrecision(*value)
197    }
198}
199
200#[cfg(feature = "rust-decimal")]
201impl From<Decimal> for PostgresValue<'_> {
202    fn from(value: Decimal) -> Self {
203        PostgresValue::Numeric(value)
204    }
205}
206
207#[cfg(feature = "rust-decimal")]
208impl<'a> From<&'a Decimal> for PostgresValue<'a> {
209    fn from(value: &'a Decimal) -> Self {
210        PostgresValue::Numeric(*value)
211    }
212}
213
214// --- Boolean ---
215
216impl From<bool> for PostgresValue<'_> {
217    fn from(value: bool) -> Self {
218        PostgresValue::Boolean(value)
219    }
220}
221
222impl<'a> From<&'a bool> for PostgresValue<'a> {
223    fn from(value: &'a bool) -> Self {
224        PostgresValue::Boolean(*value)
225    }
226}
227
228// --- String Types ---
229
230impl<'a> From<&'a str> for PostgresValue<'a> {
231    fn from(value: &'a str) -> Self {
232        PostgresValue::Text(Cow::Borrowed(value))
233    }
234}
235
236impl<'a> From<Cow<'a, str>> for PostgresValue<'a> {
237    fn from(value: Cow<'a, str>) -> Self {
238        PostgresValue::Text(value)
239    }
240}
241
242impl From<String> for PostgresValue<'_> {
243    fn from(value: String) -> Self {
244        PostgresValue::Text(Cow::Owned(value))
245    }
246}
247
248impl<'a> From<&'a String> for PostgresValue<'a> {
249    fn from(value: &'a String) -> Self {
250        PostgresValue::Text(Cow::Borrowed(value))
251    }
252}
253
254impl From<Box<String>> for PostgresValue<'_> {
255    fn from(value: Box<String>) -> Self {
256        PostgresValue::Text(Cow::Owned(*value))
257    }
258}
259
260impl<'a> From<&'a Box<String>> for PostgresValue<'a> {
261    fn from(value: &'a Box<String>) -> Self {
262        PostgresValue::Text(Cow::Borrowed(value.as_str()))
263    }
264}
265
266impl From<Rc<String>> for PostgresValue<'_> {
267    fn from(value: Rc<String>) -> Self {
268        PostgresValue::Text(Cow::Owned(value.as_ref().clone()))
269    }
270}
271
272impl<'a> From<&'a Rc<String>> for PostgresValue<'a> {
273    fn from(value: &'a Rc<String>) -> Self {
274        PostgresValue::Text(Cow::Borrowed(value.as_str()))
275    }
276}
277
278impl From<Arc<String>> for PostgresValue<'_> {
279    fn from(value: Arc<String>) -> Self {
280        PostgresValue::Text(Cow::Owned(value.as_ref().clone()))
281    }
282}
283
284impl<'a> From<&'a Arc<String>> for PostgresValue<'a> {
285    fn from(value: &'a Arc<String>) -> Self {
286        PostgresValue::Text(Cow::Borrowed(value.as_str()))
287    }
288}
289
290impl From<Box<str>> for PostgresValue<'_> {
291    fn from(value: Box<str>) -> Self {
292        PostgresValue::Text(Cow::Owned(value.into()))
293    }
294}
295
296impl<'a> From<&'a Box<str>> for PostgresValue<'a> {
297    fn from(value: &'a Box<str>) -> Self {
298        PostgresValue::Text(Cow::Borrowed(value.as_ref()))
299    }
300}
301
302impl From<Rc<str>> for PostgresValue<'_> {
303    fn from(value: Rc<str>) -> Self {
304        PostgresValue::Text(Cow::Owned(value.as_ref().to_string()))
305    }
306}
307
308impl<'a> From<&'a Rc<str>> for PostgresValue<'a> {
309    fn from(value: &'a Rc<str>) -> Self {
310        PostgresValue::Text(Cow::Borrowed(value.as_ref()))
311    }
312}
313
314impl From<Arc<str>> for PostgresValue<'_> {
315    fn from(value: Arc<str>) -> Self {
316        PostgresValue::Text(Cow::Owned(value.as_ref().to_string()))
317    }
318}
319
320impl<'a> From<&'a Arc<str>> for PostgresValue<'a> {
321    fn from(value: &'a Arc<str>) -> Self {
322        PostgresValue::Text(Cow::Borrowed(value.as_ref()))
323    }
324}
325
326// --- ArrayString ---
327
328#[cfg(feature = "arrayvec")]
329impl<const N: usize> From<arrayvec::ArrayString<N>> for PostgresValue<'_> {
330    fn from(value: arrayvec::ArrayString<N>) -> Self {
331        PostgresValue::Text(Cow::Owned(value.to_string()))
332    }
333}
334
335#[cfg(feature = "arrayvec")]
336impl<const N: usize> From<&arrayvec::ArrayString<N>> for PostgresValue<'_> {
337    fn from(value: &arrayvec::ArrayString<N>) -> Self {
338        PostgresValue::Text(Cow::Owned(String::from(value.as_str())))
339    }
340}
341
342#[cfg(feature = "compact-str")]
343impl From<compact_str::CompactString> for PostgresValue<'_> {
344    fn from(value: compact_str::CompactString) -> Self {
345        PostgresValue::Text(Cow::Owned(value.to_string()))
346    }
347}
348
349#[cfg(feature = "compact-str")]
350impl<'a> From<&'a compact_str::CompactString> for PostgresValue<'a> {
351    fn from(value: &'a compact_str::CompactString) -> Self {
352        PostgresValue::Text(Cow::Borrowed(value.as_str()))
353    }
354}
355
356// --- Binary Data ---
357
358impl<'a> From<&'a [u8]> for PostgresValue<'a> {
359    fn from(value: &'a [u8]) -> Self {
360        PostgresValue::Bytea(Cow::Borrowed(value))
361    }
362}
363
364impl<'a> From<Cow<'a, [u8]>> for PostgresValue<'a> {
365    fn from(value: Cow<'a, [u8]>) -> Self {
366        PostgresValue::Bytea(value)
367    }
368}
369
370impl From<Vec<u8>> for PostgresValue<'_> {
371    fn from(value: Vec<u8>) -> Self {
372        PostgresValue::Bytea(Cow::Owned(value))
373    }
374}
375
376impl From<Box<Vec<u8>>> for PostgresValue<'_> {
377    fn from(value: Box<Vec<u8>>) -> Self {
378        PostgresValue::Bytea(Cow::Owned(*value))
379    }
380}
381
382impl<'a> From<&'a Box<Vec<u8>>> for PostgresValue<'a> {
383    fn from(value: &'a Box<Vec<u8>>) -> Self {
384        PostgresValue::Bytea(Cow::Borrowed(value.as_slice()))
385    }
386}
387
388impl From<Rc<Vec<u8>>> for PostgresValue<'_> {
389    fn from(value: Rc<Vec<u8>>) -> Self {
390        PostgresValue::Bytea(Cow::Owned(value.as_ref().clone()))
391    }
392}
393
394impl<'a> From<&'a Rc<Vec<u8>>> for PostgresValue<'a> {
395    fn from(value: &'a Rc<Vec<u8>>) -> Self {
396        PostgresValue::Bytea(Cow::Borrowed(value.as_slice()))
397    }
398}
399
400impl From<Arc<Vec<u8>>> for PostgresValue<'_> {
401    fn from(value: Arc<Vec<u8>>) -> Self {
402        PostgresValue::Bytea(Cow::Owned(value.as_ref().clone()))
403    }
404}
405
406impl<'a> From<&'a Arc<Vec<u8>>> for PostgresValue<'a> {
407    fn from(value: &'a Arc<Vec<u8>>) -> Self {
408        PostgresValue::Bytea(Cow::Borrowed(value.as_slice()))
409    }
410}
411
412// --- ArrayVec<u8, N> ---
413
414#[cfg(feature = "arrayvec")]
415impl<const N: usize> From<arrayvec::ArrayVec<u8, N>> for PostgresValue<'_> {
416    fn from(value: arrayvec::ArrayVec<u8, N>) -> Self {
417        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
418    }
419}
420
421#[cfg(feature = "arrayvec")]
422impl<const N: usize> From<&arrayvec::ArrayVec<u8, N>> for PostgresValue<'_> {
423    fn from(value: &arrayvec::ArrayVec<u8, N>) -> Self {
424        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
425    }
426}
427
428#[cfg(feature = "bytes")]
429impl From<bytes::Bytes> for PostgresValue<'_> {
430    fn from(value: bytes::Bytes) -> Self {
431        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
432    }
433}
434
435#[cfg(feature = "bytes")]
436impl<'a> From<&'a bytes::Bytes> for PostgresValue<'a> {
437    fn from(value: &'a bytes::Bytes) -> Self {
438        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
439    }
440}
441
442#[cfg(feature = "bytes")]
443impl From<bytes::BytesMut> for PostgresValue<'_> {
444    fn from(value: bytes::BytesMut) -> Self {
445        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
446    }
447}
448
449#[cfg(feature = "bytes")]
450impl<'a> From<&'a bytes::BytesMut> for PostgresValue<'a> {
451    fn from(value: &'a bytes::BytesMut) -> Self {
452        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
453    }
454}
455
456#[cfg(feature = "smallvec")]
457impl<const N: usize> From<smallvec::SmallVec<[u8; N]>> for PostgresValue<'_> {
458    fn from(value: smallvec::SmallVec<[u8; N]>) -> Self {
459        PostgresValue::Bytea(Cow::Owned(value.into_vec()))
460    }
461}
462
463#[cfg(feature = "smallvec")]
464impl<const N: usize> From<&smallvec::SmallVec<[u8; N]>> for PostgresValue<'_> {
465    fn from(value: &smallvec::SmallVec<[u8; N]>) -> Self {
466        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
467    }
468}
469
470// --- UUID ---
471
472#[cfg(feature = "uuid")]
473impl From<Uuid> for PostgresValue<'_> {
474    fn from(value: Uuid) -> Self {
475        PostgresValue::Uuid(value)
476    }
477}
478
479#[cfg(feature = "uuid")]
480impl<'a> From<&'a Uuid> for PostgresValue<'a> {
481    fn from(value: &'a Uuid) -> Self {
482        PostgresValue::Uuid(*value)
483    }
484}
485
486// --- JSON ---
487
488#[cfg(feature = "serde")]
489impl From<serde_json::Value> for PostgresValue<'_> {
490    fn from(value: serde_json::Value) -> Self {
491        PostgresValue::Json(value)
492    }
493}
494
495#[cfg(feature = "serde")]
496impl<'a> From<&'a serde_json::Value> for PostgresValue<'a> {
497    fn from(value: &'a serde_json::Value) -> Self {
498        PostgresValue::Json(value.clone())
499    }
500}
501
502// --- Date/Time Types ---
503
504#[cfg(feature = "chrono")]
505impl From<NaiveDate> for PostgresValue<'_> {
506    fn from(value: NaiveDate) -> Self {
507        PostgresValue::Date(value)
508    }
509}
510
511#[cfg(feature = "chrono")]
512impl<'a> From<&'a NaiveDate> for PostgresValue<'a> {
513    fn from(value: &'a NaiveDate) -> Self {
514        PostgresValue::Date(*value)
515    }
516}
517
518#[cfg(feature = "chrono")]
519impl From<NaiveTime> for PostgresValue<'_> {
520    fn from(value: NaiveTime) -> Self {
521        PostgresValue::Time(value)
522    }
523}
524
525#[cfg(feature = "chrono")]
526impl<'a> From<&'a NaiveTime> for PostgresValue<'a> {
527    fn from(value: &'a NaiveTime) -> Self {
528        PostgresValue::Time(*value)
529    }
530}
531
532#[cfg(feature = "chrono")]
533impl From<NaiveDateTime> for PostgresValue<'_> {
534    fn from(value: NaiveDateTime) -> Self {
535        PostgresValue::Timestamp(value)
536    }
537}
538
539#[cfg(feature = "chrono")]
540impl<'a> From<&'a NaiveDateTime> for PostgresValue<'a> {
541    fn from(value: &'a NaiveDateTime) -> Self {
542        PostgresValue::Timestamp(*value)
543    }
544}
545
546#[cfg(feature = "chrono")]
547impl From<DateTime<FixedOffset>> for PostgresValue<'_> {
548    fn from(value: DateTime<FixedOffset>) -> Self {
549        PostgresValue::TimestampTz(value)
550    }
551}
552
553#[cfg(feature = "chrono")]
554impl<'a> From<&'a DateTime<FixedOffset>> for PostgresValue<'a> {
555    fn from(value: &'a DateTime<FixedOffset>) -> Self {
556        PostgresValue::TimestampTz(*value)
557    }
558}
559
560#[cfg(feature = "chrono")]
561impl From<DateTime<Utc>> for PostgresValue<'_> {
562    fn from(value: DateTime<Utc>) -> Self {
563        PostgresValue::TimestampTz(value.into())
564    }
565}
566
567#[cfg(feature = "chrono")]
568impl<'a> From<&'a DateTime<Utc>> for PostgresValue<'a> {
569    fn from(value: &'a DateTime<Utc>) -> Self {
570        PostgresValue::TimestampTz((*value).into())
571    }
572}
573
574#[cfg(feature = "chrono")]
575impl From<Duration> for PostgresValue<'_> {
576    fn from(value: Duration) -> Self {
577        PostgresValue::Interval(value)
578    }
579}
580
581#[cfg(feature = "chrono")]
582impl<'a> From<&'a Duration> for PostgresValue<'a> {
583    fn from(value: &'a Duration) -> Self {
584        PostgresValue::Interval(*value)
585    }
586}
587
588// --- Date/Time Types (time crate) ---
589
590#[cfg(feature = "time")]
591impl From<TimeDate> for PostgresValue<'_> {
592    fn from(value: TimeDate) -> Self {
593        PostgresValue::TimeDate(value)
594    }
595}
596
597#[cfg(feature = "time")]
598impl<'a> From<&'a TimeDate> for PostgresValue<'a> {
599    fn from(value: &'a TimeDate) -> Self {
600        PostgresValue::TimeDate(*value)
601    }
602}
603
604#[cfg(feature = "time")]
605impl From<TimeTime> for PostgresValue<'_> {
606    fn from(value: TimeTime) -> Self {
607        PostgresValue::TimeTime(value)
608    }
609}
610
611#[cfg(feature = "time")]
612impl<'a> From<&'a TimeTime> for PostgresValue<'a> {
613    fn from(value: &'a TimeTime) -> Self {
614        PostgresValue::TimeTime(*value)
615    }
616}
617
618#[cfg(feature = "time")]
619impl From<PrimitiveDateTime> for PostgresValue<'_> {
620    fn from(value: PrimitiveDateTime) -> Self {
621        PostgresValue::TimeTimestamp(value)
622    }
623}
624
625#[cfg(feature = "time")]
626impl<'a> From<&'a PrimitiveDateTime> for PostgresValue<'a> {
627    fn from(value: &'a PrimitiveDateTime) -> Self {
628        PostgresValue::TimeTimestamp(*value)
629    }
630}
631
632#[cfg(feature = "time")]
633impl From<OffsetDateTime> for PostgresValue<'_> {
634    fn from(value: OffsetDateTime) -> Self {
635        PostgresValue::TimeTimestampTz(value)
636    }
637}
638
639#[cfg(feature = "time")]
640impl<'a> From<&'a OffsetDateTime> for PostgresValue<'a> {
641    fn from(value: &'a OffsetDateTime) -> Self {
642        PostgresValue::TimeTimestampTz(*value)
643    }
644}
645
646#[cfg(feature = "time")]
647impl From<TimeDuration> for PostgresValue<'_> {
648    fn from(value: TimeDuration) -> Self {
649        PostgresValue::TimeInterval(value)
650    }
651}
652
653#[cfg(feature = "time")]
654impl<'a> From<&'a TimeDuration> for PostgresValue<'a> {
655    fn from(value: &'a TimeDuration) -> Self {
656        PostgresValue::TimeInterval(*value)
657    }
658}
659
660#[cfg(feature = "jiff")]
661impl From<JiffDate> for PostgresValue<'_> {
662    fn from(value: JiffDate) -> Self {
663        PostgresValue::JiffDate(value)
664    }
665}
666
667#[cfg(feature = "jiff")]
668impl<'a> From<&'a JiffDate> for PostgresValue<'a> {
669    fn from(value: &'a JiffDate) -> Self {
670        PostgresValue::JiffDate(*value)
671    }
672}
673
674#[cfg(feature = "jiff")]
675impl From<JiffTime> for PostgresValue<'_> {
676    fn from(value: JiffTime) -> Self {
677        PostgresValue::JiffTime(value)
678    }
679}
680
681#[cfg(feature = "jiff")]
682impl<'a> From<&'a JiffTime> for PostgresValue<'a> {
683    fn from(value: &'a JiffTime) -> Self {
684        PostgresValue::JiffTime(*value)
685    }
686}
687
688#[cfg(feature = "jiff")]
689impl From<JiffDateTime> for PostgresValue<'_> {
690    fn from(value: JiffDateTime) -> Self {
691        PostgresValue::JiffDateTime(value)
692    }
693}
694
695#[cfg(feature = "jiff")]
696impl<'a> From<&'a JiffDateTime> for PostgresValue<'a> {
697    fn from(value: &'a JiffDateTime) -> Self {
698        PostgresValue::JiffDateTime(*value)
699    }
700}
701
702#[cfg(feature = "jiff")]
703impl From<JiffTimestamp> for PostgresValue<'_> {
704    fn from(value: JiffTimestamp) -> Self {
705        PostgresValue::JiffTimestamp(value)
706    }
707}
708
709#[cfg(feature = "jiff")]
710impl<'a> From<&'a JiffTimestamp> for PostgresValue<'a> {
711    fn from(value: &'a JiffTimestamp) -> Self {
712        PostgresValue::JiffTimestamp(*value)
713    }
714}
715
716// --- Network Address Types ---
717
718#[cfg(feature = "cidr")]
719impl From<IpInet> for PostgresValue<'_> {
720    fn from(value: IpInet) -> Self {
721        PostgresValue::Inet(value)
722    }
723}
724
725#[cfg(feature = "cidr")]
726impl<'a> From<&'a IpInet> for PostgresValue<'a> {
727    fn from(value: &'a IpInet) -> Self {
728        PostgresValue::Inet(*value)
729    }
730}
731
732#[cfg(feature = "cidr")]
733impl From<IpCidr> for PostgresValue<'_> {
734    fn from(value: IpCidr) -> Self {
735        PostgresValue::Cidr(value)
736    }
737}
738
739#[cfg(feature = "cidr")]
740impl<'a> From<&'a IpCidr> for PostgresValue<'a> {
741    fn from(value: &'a IpCidr) -> Self {
742        PostgresValue::Cidr(*value)
743    }
744}
745
746#[cfg(feature = "cidr")]
747impl From<[u8; 6]> for PostgresValue<'_> {
748    fn from(value: [u8; 6]) -> Self {
749        PostgresValue::MacAddr(value)
750    }
751}
752
753#[cfg(feature = "cidr")]
754impl<'a> From<&'a [u8; 6]> for PostgresValue<'a> {
755    fn from(value: &'a [u8; 6]) -> Self {
756        PostgresValue::MacAddr(*value)
757    }
758}
759
760#[cfg(feature = "cidr")]
761impl From<[u8; 8]> for PostgresValue<'_> {
762    fn from(value: [u8; 8]) -> Self {
763        PostgresValue::MacAddr8(value)
764    }
765}
766
767#[cfg(feature = "cidr")]
768impl<'a> From<&'a [u8; 8]> for PostgresValue<'a> {
769    fn from(value: &'a [u8; 8]) -> Self {
770        PostgresValue::MacAddr8(*value)
771    }
772}
773
774// --- Geometric Types ---
775
776#[cfg(feature = "geo-types")]
777impl From<Point<f64>> for PostgresValue<'_> {
778    fn from(value: Point<f64>) -> Self {
779        PostgresValue::Point(value)
780    }
781}
782
783#[cfg(feature = "geo-types")]
784impl<'a> From<&'a Point<f64>> for PostgresValue<'a> {
785    fn from(value: &'a Point<f64>) -> Self {
786        PostgresValue::Point(*value)
787    }
788}
789
790#[cfg(feature = "geo-types")]
791impl From<LineString<f64>> for PostgresValue<'_> {
792    fn from(value: LineString<f64>) -> Self {
793        PostgresValue::LineString(value)
794    }
795}
796
797#[cfg(feature = "geo-types")]
798impl<'a> From<&'a LineString<f64>> for PostgresValue<'a> {
799    fn from(value: &'a LineString<f64>) -> Self {
800        PostgresValue::LineString(value.clone())
801    }
802}
803
804#[cfg(feature = "geo-types")]
805impl From<Rect<f64>> for PostgresValue<'_> {
806    fn from(value: Rect<f64>) -> Self {
807        PostgresValue::Rect(value)
808    }
809}
810
811#[cfg(feature = "geo-types")]
812impl<'a> From<&'a Rect<f64>> for PostgresValue<'a> {
813    fn from(value: &'a Rect<f64>) -> Self {
814        PostgresValue::Rect(*value)
815    }
816}
817
818// --- Bit String Types ---
819
820#[cfg(feature = "bit-vec")]
821impl From<BitVec> for PostgresValue<'_> {
822    fn from(value: BitVec) -> Self {
823        PostgresValue::BitVec(value)
824    }
825}
826
827#[cfg(feature = "bit-vec")]
828impl<'a> From<&'a BitVec> for PostgresValue<'a> {
829    fn from(value: &'a BitVec) -> Self {
830        PostgresValue::BitVec(value.clone())
831    }
832}
833
834// --- Array Types ---
835
836impl From<Vec<Self>> for PostgresValue<'_> {
837    fn from(value: Vec<Self>) -> Self {
838        PostgresValue::Array(value)
839    }
840}
841
842impl<'a> From<&'a [Self]> for PostgresValue<'a> {
843    fn from(value: &'a [Self]) -> Self {
844        PostgresValue::Array(value.to_vec())
845    }
846}
847
848impl From<Vec<String>> for PostgresValue<'_> {
849    fn from(value: Vec<String>) -> Self {
850        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
851    }
852}
853
854impl<'a> From<Vec<&'a str>> for PostgresValue<'a> {
855    fn from(value: Vec<&'a str>) -> Self {
856        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
857    }
858}
859
860impl From<Vec<i16>> for PostgresValue<'_> {
861    fn from(value: Vec<i16>) -> Self {
862        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
863    }
864}
865
866impl From<Vec<i32>> for PostgresValue<'_> {
867    fn from(value: Vec<i32>) -> Self {
868        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
869    }
870}
871
872impl From<Vec<i64>> for PostgresValue<'_> {
873    fn from(value: Vec<i64>) -> Self {
874        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
875    }
876}
877
878impl From<Vec<f32>> for PostgresValue<'_> {
879    fn from(value: Vec<f32>) -> Self {
880        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
881    }
882}
883
884impl From<Vec<f64>> for PostgresValue<'_> {
885    fn from(value: Vec<f64>) -> Self {
886        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
887    }
888}
889
890impl From<Vec<bool>> for PostgresValue<'_> {
891    fn from(value: Vec<bool>) -> Self {
892        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
893    }
894}
895
896// --- Extended Array Types ---
897
898#[cfg(feature = "uuid")]
899impl From<Vec<uuid::Uuid>> for PostgresValue<'_> {
900    fn from(value: Vec<uuid::Uuid>) -> Self {
901        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
902    }
903}
904
905#[cfg(feature = "chrono")]
906impl From<Vec<NaiveDate>> for PostgresValue<'_> {
907    fn from(value: Vec<NaiveDate>) -> Self {
908        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
909    }
910}
911
912#[cfg(feature = "chrono")]
913impl From<Vec<NaiveTime>> for PostgresValue<'_> {
914    fn from(value: Vec<NaiveTime>) -> Self {
915        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
916    }
917}
918
919#[cfg(feature = "chrono")]
920impl From<Vec<NaiveDateTime>> for PostgresValue<'_> {
921    fn from(value: Vec<NaiveDateTime>) -> Self {
922        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
923    }
924}
925
926#[cfg(feature = "chrono")]
927impl From<Vec<DateTime<Utc>>> for PostgresValue<'_> {
928    fn from(value: Vec<DateTime<Utc>>) -> Self {
929        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
930    }
931}
932
933#[cfg(feature = "rust-decimal")]
934impl From<Vec<Decimal>> for PostgresValue<'_> {
935    fn from(value: Vec<Decimal>) -> Self {
936        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
937    }
938}
939
940// --- Option Types ---
941/// `None` is NULL.
942///
943/// # Panics
944///
945/// Panics when `T`'s conversion fails (for example a JSON payload whose
946/// `Serialize` implementation errors), rather than storing NULL in place of
947/// the value.
948impl<T> From<Option<T>> for PostgresValue<'_>
949where
950    T: TryInto<Self>,
951{
952    fn from(value: Option<T>) -> Self {
953        value.map_or(PostgresValue::Null, |v| {
954            v.try_into().unwrap_or_else(|_| {
955                panic!(
956                    "could not convert a `{}` to a PostgreSQL value",
957                    core::any::type_name::<T>()
958                )
959            })
960        })
961    }
962}
963
964//------------------------------------------------------------------------------
965// TryFrom<PostgresValue> implementations
966//------------------------------------------------------------------------------
967
968// --- Integer Types ---
969
970impl<'a> TryFrom<PostgresValue<'a>> for i16 {
971    type Error = DrizzleError;
972
973    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
974        match value {
975            PostgresValue::Smallint(i) => Ok(i),
976            PostgresValue::Integer(i) => Ok(i.try_into()?),
977            PostgresValue::Bigint(i) => Ok(i.try_into()?),
978            _ => Err(DrizzleError::ConversionError(
979                format!("Cannot convert {value:?} to i16").into(),
980            )),
981        }
982    }
983}
984
985impl<'a> TryFrom<PostgresValue<'a>> for i32 {
986    type Error = DrizzleError;
987
988    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
989        match value {
990            PostgresValue::Smallint(i) => Ok(i.into()),
991            PostgresValue::Integer(i) => Ok(i),
992            PostgresValue::Bigint(i) => Ok(i.try_into()?),
993            _ => Err(DrizzleError::ConversionError(
994                format!("Cannot convert {value:?} to i32").into(),
995            )),
996        }
997    }
998}
999
1000impl<'a> TryFrom<PostgresValue<'a>> for i64 {
1001    type Error = DrizzleError;
1002
1003    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1004        match value {
1005            PostgresValue::Smallint(i) => Ok(i.into()),
1006            PostgresValue::Integer(i) => Ok(i.into()),
1007            PostgresValue::Bigint(i) => Ok(i),
1008            _ => Err(DrizzleError::ConversionError(
1009                format!("Cannot convert {value:?} to i64").into(),
1010            )),
1011        }
1012    }
1013}
1014
1015// --- Floating Point Types ---
1016
1017impl<'a> TryFrom<PostgresValue<'a>> for f32 {
1018    type Error = DrizzleError;
1019
1020    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1021        fn parse_float<N: core::fmt::Display>(value: N) -> Result<f32, DrizzleError> {
1022            let s = format!("{value}");
1023            s.parse::<f32>().map_err(|e| {
1024                DrizzleError::ConversionError(format!("Failed to convert {s} to f32: {e}").into())
1025            })
1026        }
1027
1028        match value {
1029            PostgresValue::Real(f) => Ok(f),
1030            PostgresValue::DoublePrecision(f) => parse_float(f),
1031            PostgresValue::Smallint(i) => Ok(Self::from(i)),
1032            PostgresValue::Integer(i) => parse_float(i),
1033            PostgresValue::Bigint(i) => parse_float(i),
1034            _ => Err(DrizzleError::ConversionError(
1035                format!("Cannot convert {value:?} to f32").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(Self::from(f)),
1047            PostgresValue::DoublePrecision(f) => Ok(f),
1048            PostgresValue::Smallint(i) => Ok(Self::from(i)),
1049            PostgresValue::Integer(i) => Ok(Self::from(i)),
1050            PostgresValue::Bigint(i) => {
1051                let s = format!("{i}");
1052                s.parse::<Self>().map_err(|e| {
1053                    DrizzleError::ConversionError(
1054                        format!("Failed to convert {s} to f64: {e}").into(),
1055                    )
1056                })
1057            }
1058            _ => Err(DrizzleError::ConversionError(
1059                format!("Cannot convert {value:?} to f64").into(),
1060            )),
1061        }
1062    }
1063}
1064
1065#[cfg(feature = "rust-decimal")]
1066impl<'a> TryFrom<PostgresValue<'a>> for Decimal {
1067    type Error = DrizzleError;
1068
1069    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1070        match value {
1071            PostgresValue::Numeric(d) => Ok(d),
1072            PostgresValue::Text(cow) => Self::from_str_exact(cow.as_ref()).map_err(|e| {
1073                DrizzleError::ConversionError(format!("Failed to parse DECIMAL: {e}").into())
1074            }),
1075            _ => Err(DrizzleError::ConversionError(
1076                format!("Cannot convert {value:?} to Decimal").into(),
1077            )),
1078        }
1079    }
1080}
1081
1082#[cfg(feature = "rust-decimal")]
1083impl<'a> TryFrom<&'a PostgresValue<'a>> for Decimal {
1084    type Error = DrizzleError;
1085
1086    fn try_from(value: &'a PostgresValue<'a>) -> Result<Self, Self::Error> {
1087        match value {
1088            PostgresValue::Numeric(d) => Ok(*d),
1089            PostgresValue::Text(cow) => Self::from_str_exact(cow.as_ref()).map_err(|e| {
1090                DrizzleError::ConversionError(format!("Failed to parse DECIMAL: {e}").into())
1091            }),
1092            _ => Err(DrizzleError::ConversionError(
1093                format!("Cannot convert {value:?} to Decimal").into(),
1094            )),
1095        }
1096    }
1097}
1098
1099// --- Boolean ---
1100
1101impl<'a> TryFrom<PostgresValue<'a>> for bool {
1102    type Error = DrizzleError;
1103
1104    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1105        match value {
1106            PostgresValue::Boolean(b) => Ok(b),
1107            _ => Err(DrizzleError::ConversionError(
1108                format!("Cannot convert {value:?} to bool").into(),
1109            )),
1110        }
1111    }
1112}
1113
1114// --- String Types ---
1115
1116impl<'a> TryFrom<PostgresValue<'a>> for String {
1117    type Error = DrizzleError;
1118
1119    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1120        match value {
1121            PostgresValue::Text(cow) => Ok(cow.into_owned()),
1122            _ => Err(DrizzleError::ConversionError(
1123                format!("Cannot convert {value:?} to String").into(),
1124            )),
1125        }
1126    }
1127}
1128
1129impl<'a> TryFrom<PostgresValue<'a>> for Box<String> {
1130    type Error = DrizzleError;
1131
1132    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1133        String::try_from(value).map(Self::new)
1134    }
1135}
1136
1137impl<'a> TryFrom<PostgresValue<'a>> for Rc<String> {
1138    type Error = DrizzleError;
1139
1140    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1141        String::try_from(value).map(Self::new)
1142    }
1143}
1144
1145impl<'a> TryFrom<PostgresValue<'a>> for Arc<String> {
1146    type Error = DrizzleError;
1147
1148    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1149        String::try_from(value).map(Self::new)
1150    }
1151}
1152
1153impl<'a> TryFrom<PostgresValue<'a>> for Box<str> {
1154    type Error = DrizzleError;
1155
1156    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1157        match value {
1158            PostgresValue::Text(cow) => Ok(cow.into_owned().into_boxed_str()),
1159            _ => Err(DrizzleError::ConversionError(
1160                format!("Cannot convert {value:?} to Box<str>").into(),
1161            )),
1162        }
1163    }
1164}
1165
1166impl<'a> TryFrom<PostgresValue<'a>> for Rc<str> {
1167    type Error = DrizzleError;
1168
1169    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1170        match value {
1171            PostgresValue::Text(cow) => Ok(Self::from(cow.into_owned())),
1172            _ => Err(DrizzleError::ConversionError(
1173                format!("Cannot convert {value:?} to Rc<str>").into(),
1174            )),
1175        }
1176    }
1177}
1178
1179impl<'a> TryFrom<PostgresValue<'a>> for Arc<str> {
1180    type Error = DrizzleError;
1181
1182    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1183        match value {
1184            PostgresValue::Text(cow) => Ok(Self::from(cow.into_owned())),
1185            _ => Err(DrizzleError::ConversionError(
1186                format!("Cannot convert {value:?} to Arc<str>").into(),
1187            )),
1188        }
1189    }
1190}
1191
1192#[cfg(feature = "compact-str")]
1193impl<'a> TryFrom<PostgresValue<'a>> for compact_str::CompactString {
1194    type Error = DrizzleError;
1195
1196    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1197        String::try_from(value).map(Self::new)
1198    }
1199}
1200
1201// --- Binary Data ---
1202
1203impl<'a> TryFrom<PostgresValue<'a>> for Vec<u8> {
1204    type Error = DrizzleError;
1205
1206    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1207        match value {
1208            PostgresValue::Bytea(cow) => Ok(cow.into_owned()),
1209            _ => Err(DrizzleError::ConversionError(
1210                format!("Cannot convert {value:?} to Vec<u8>").into(),
1211            )),
1212        }
1213    }
1214}
1215
1216impl<'a> TryFrom<PostgresValue<'a>> for Box<Vec<u8>> {
1217    type Error = DrizzleError;
1218
1219    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1220        Vec::<u8>::try_from(value).map(Self::new)
1221    }
1222}
1223
1224impl<'a> TryFrom<PostgresValue<'a>> for Rc<Vec<u8>> {
1225    type Error = DrizzleError;
1226
1227    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1228        Vec::<u8>::try_from(value).map(Self::new)
1229    }
1230}
1231
1232impl<'a> TryFrom<PostgresValue<'a>> for Arc<Vec<u8>> {
1233    type Error = DrizzleError;
1234
1235    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1236        Vec::<u8>::try_from(value).map(Self::new)
1237    }
1238}
1239
1240#[cfg(feature = "bytes")]
1241impl<'a> TryFrom<PostgresValue<'a>> for bytes::Bytes {
1242    type Error = DrizzleError;
1243
1244    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1245        Vec::<u8>::try_from(value).map(Self::from)
1246    }
1247}
1248
1249#[cfg(feature = "bytes")]
1250impl<'a> TryFrom<PostgresValue<'a>> for bytes::BytesMut {
1251    type Error = DrizzleError;
1252
1253    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1254        Vec::<u8>::try_from(value).map(|v| Self::from(v.as_slice()))
1255    }
1256}
1257
1258#[cfg(feature = "smallvec")]
1259impl<'a, const N: usize> TryFrom<PostgresValue<'a>> for smallvec::SmallVec<[u8; N]> {
1260    type Error = DrizzleError;
1261
1262    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1263        Vec::<u8>::try_from(value).map(|v| {
1264            let mut out = Self::new();
1265            out.extend_from_slice(&v);
1266            out
1267        })
1268    }
1269}
1270
1271impl<'a> TryFrom<&'a PostgresValue<'a>> for &'a str {
1272    type Error = DrizzleError;
1273
1274    fn try_from(value: &'a PostgresValue<'a>) -> Result<Self, Self::Error> {
1275        match value {
1276            PostgresValue::Text(cow) => Ok(cow.as_ref()),
1277            _ => Err(DrizzleError::ConversionError(
1278                format!("Cannot convert {value:?} to &str").into(),
1279            )),
1280        }
1281    }
1282}
1283
1284impl<'a> TryFrom<&'a PostgresValue<'a>> for &'a [u8] {
1285    type Error = DrizzleError;
1286
1287    fn try_from(value: &'a PostgresValue<'a>) -> Result<Self, Self::Error> {
1288        match value {
1289            PostgresValue::Bytea(cow) => Ok(cow.as_ref()),
1290            _ => Err(DrizzleError::ConversionError(
1291                format!("Cannot convert {value:?} to &[u8]").into(),
1292            )),
1293        }
1294    }
1295}
1296
1297// --- UUID ---
1298
1299#[cfg(feature = "uuid")]
1300impl<'a> TryFrom<PostgresValue<'a>> for Uuid {
1301    type Error = DrizzleError;
1302
1303    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1304        match value {
1305            PostgresValue::Uuid(uuid) => Ok(uuid),
1306            PostgresValue::Text(cow) => Self::parse_str(cow.as_ref()).map_err(|e| {
1307                DrizzleError::ConversionError(format!("Failed to parse UUID: {e}").into())
1308            }),
1309            _ => Err(DrizzleError::ConversionError(
1310                format!("Cannot convert {value:?} to UUID").into(),
1311            )),
1312        }
1313    }
1314}
1315
1316// --- JSON ---
1317
1318#[cfg(feature = "serde")]
1319impl<'a> TryFrom<PostgresValue<'a>> for serde_json::Value {
1320    type Error = DrizzleError;
1321
1322    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1323        match value {
1324            PostgresValue::Json(json) | PostgresValue::Jsonb(json) => Ok(json),
1325            PostgresValue::Text(cow) => serde_json::from_str(cow.as_ref()).map_err(|e| {
1326                DrizzleError::ConversionError(format!("Failed to parse JSON: {e}").into())
1327            }),
1328            _ => Err(DrizzleError::ConversionError(
1329                format!("Cannot convert {value:?} to JSON").into(),
1330            )),
1331        }
1332    }
1333}
1334
1335// --- Date/Time TryFrom implementations ---
1336
1337#[cfg(feature = "chrono")]
1338impl<'a> TryFrom<PostgresValue<'a>> for NaiveDate {
1339    type Error = DrizzleError;
1340
1341    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1342        match value {
1343            PostgresValue::Date(date) => Ok(date),
1344            PostgresValue::Timestamp(ts) => Ok(ts.date()),
1345            PostgresValue::TimestampTz(ts) => Ok(ts.date_naive()),
1346            _ => Err(DrizzleError::ConversionError(
1347                format!("Cannot convert {value:?} to NaiveDate").into(),
1348            )),
1349        }
1350    }
1351}
1352
1353#[cfg(feature = "chrono")]
1354impl<'a> TryFrom<PostgresValue<'a>> for NaiveTime {
1355    type Error = DrizzleError;
1356
1357    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1358        match value {
1359            PostgresValue::Time(time) => Ok(time),
1360            PostgresValue::Timestamp(ts) => Ok(ts.time()),
1361            PostgresValue::TimestampTz(ts) => Ok(ts.time()),
1362            _ => Err(DrizzleError::ConversionError(
1363                format!("Cannot convert {value:?} to NaiveTime").into(),
1364            )),
1365        }
1366    }
1367}
1368
1369#[cfg(feature = "chrono")]
1370impl<'a> TryFrom<PostgresValue<'a>> for NaiveDateTime {
1371    type Error = DrizzleError;
1372
1373    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1374        match value {
1375            PostgresValue::Timestamp(ts) => Ok(ts),
1376            PostgresValue::TimestampTz(ts) => Ok(ts.naive_utc()),
1377            _ => Err(DrizzleError::ConversionError(
1378                format!("Cannot convert {value:?} to NaiveDateTime").into(),
1379            )),
1380        }
1381    }
1382}
1383
1384#[cfg(feature = "chrono")]
1385impl<'a> TryFrom<PostgresValue<'a>> for DateTime<FixedOffset> {
1386    type Error = DrizzleError;
1387
1388    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1389        match value {
1390            PostgresValue::TimestampTz(ts) => Ok(ts),
1391            _ => Err(DrizzleError::ConversionError(
1392                format!("Cannot convert {value:?} to DateTime<FixedOffset>").into(),
1393            )),
1394        }
1395    }
1396}
1397
1398#[cfg(feature = "chrono")]
1399impl<'a> TryFrom<PostgresValue<'a>> for DateTime<Utc> {
1400    type Error = DrizzleError;
1401
1402    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1403        match value {
1404            PostgresValue::TimestampTz(ts) => Ok(ts.with_timezone(&Utc)),
1405            _ => Err(DrizzleError::ConversionError(
1406                format!("Cannot convert {value:?} to DateTime<Utc>").into(),
1407            )),
1408        }
1409    }
1410}
1411
1412#[cfg(feature = "chrono")]
1413impl<'a> TryFrom<PostgresValue<'a>> for Duration {
1414    type Error = DrizzleError;
1415
1416    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1417        match value {
1418            PostgresValue::Interval(duration) => Ok(duration),
1419            _ => Err(DrizzleError::ConversionError(
1420                format!("Cannot convert {value:?} to Duration").into(),
1421            )),
1422        }
1423    }
1424}
1425
1426// --- Date/Time TryFrom implementations (time crate) ---
1427
1428#[cfg(feature = "time")]
1429impl<'a> TryFrom<PostgresValue<'a>> for TimeDate {
1430    type Error = DrizzleError;
1431
1432    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1433        match value {
1434            PostgresValue::TimeDate(date) => Ok(date),
1435            PostgresValue::TimeTimestamp(ts) => Ok(ts.date()),
1436            PostgresValue::TimeTimestampTz(ts) => Ok(ts.date()),
1437            _ => Err(DrizzleError::ConversionError(
1438                format!("Cannot convert {value:?} to time::Date").into(),
1439            )),
1440        }
1441    }
1442}
1443
1444#[cfg(feature = "time")]
1445impl<'a> TryFrom<PostgresValue<'a>> for TimeTime {
1446    type Error = DrizzleError;
1447
1448    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1449        match value {
1450            PostgresValue::TimeTime(time) => Ok(time),
1451            PostgresValue::TimeTimestamp(ts) => Ok(ts.time()),
1452            PostgresValue::TimeTimestampTz(ts) => Ok(ts.time()),
1453            _ => Err(DrizzleError::ConversionError(
1454                format!("Cannot convert {value:?} to time::Time").into(),
1455            )),
1456        }
1457    }
1458}
1459
1460#[cfg(feature = "time")]
1461impl<'a> TryFrom<PostgresValue<'a>> for PrimitiveDateTime {
1462    type Error = DrizzleError;
1463
1464    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1465        match value {
1466            PostgresValue::TimeTimestamp(ts) => Ok(ts),
1467            _ => Err(DrizzleError::ConversionError(
1468                format!("Cannot convert {value:?} to time::PrimitiveDateTime").into(),
1469            )),
1470        }
1471    }
1472}
1473
1474#[cfg(feature = "time")]
1475impl<'a> TryFrom<PostgresValue<'a>> for OffsetDateTime {
1476    type Error = DrizzleError;
1477
1478    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1479        match value {
1480            PostgresValue::TimeTimestampTz(ts) => Ok(ts),
1481            _ => Err(DrizzleError::ConversionError(
1482                format!("Cannot convert {value:?} to time::OffsetDateTime").into(),
1483            )),
1484        }
1485    }
1486}
1487
1488#[cfg(feature = "time")]
1489impl<'a> TryFrom<PostgresValue<'a>> for TimeDuration {
1490    type Error = DrizzleError;
1491
1492    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1493        match value {
1494            PostgresValue::TimeInterval(dur) => Ok(dur),
1495            _ => Err(DrizzleError::ConversionError(
1496                format!("Cannot convert {value:?} to time::Duration").into(),
1497            )),
1498        }
1499    }
1500}
1501
1502#[cfg(feature = "jiff")]
1503impl<'a> TryFrom<PostgresValue<'a>> for JiffDate {
1504    type Error = DrizzleError;
1505
1506    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1507        match value {
1508            PostgresValue::JiffDate(date) => Ok(date),
1509            PostgresValue::JiffDateTime(ts) => Ok(ts.date()),
1510            PostgresValue::JiffTimestamp(ts) => Ok(jiff::tz::Offset::UTC.to_datetime(ts).date()),
1511            _ => Err(DrizzleError::ConversionError(
1512                format!("Cannot convert {value:?} to jiff::civil::Date").into(),
1513            )),
1514        }
1515    }
1516}
1517
1518#[cfg(feature = "jiff")]
1519impl<'a> TryFrom<PostgresValue<'a>> for JiffTime {
1520    type Error = DrizzleError;
1521
1522    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1523        match value {
1524            PostgresValue::JiffTime(time) => Ok(time),
1525            PostgresValue::JiffDateTime(ts) => Ok(ts.time()),
1526            PostgresValue::JiffTimestamp(ts) => Ok(jiff::tz::Offset::UTC.to_datetime(ts).time()),
1527            _ => Err(DrizzleError::ConversionError(
1528                format!("Cannot convert {value:?} to jiff::civil::Time").into(),
1529            )),
1530        }
1531    }
1532}
1533
1534#[cfg(feature = "jiff")]
1535impl<'a> TryFrom<PostgresValue<'a>> for JiffDateTime {
1536    type Error = DrizzleError;
1537
1538    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1539        match value {
1540            PostgresValue::JiffDateTime(ts) => Ok(ts),
1541            _ => Err(DrizzleError::ConversionError(
1542                format!("Cannot convert {value:?} to jiff::civil::DateTime").into(),
1543            )),
1544        }
1545    }
1546}
1547
1548#[cfg(feature = "jiff")]
1549impl<'a> TryFrom<PostgresValue<'a>> for JiffTimestamp {
1550    type Error = DrizzleError;
1551
1552    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1553        match value {
1554            PostgresValue::JiffTimestamp(ts) => Ok(ts),
1555            _ => Err(DrizzleError::ConversionError(
1556                format!("Cannot convert {value:?} to jiff::Timestamp").into(),
1557            )),
1558        }
1559    }
1560}
1561
1562// --- Network Address TryFrom implementations ---
1563
1564#[cfg(feature = "cidr")]
1565impl<'a> TryFrom<PostgresValue<'a>> for IpInet {
1566    type Error = DrizzleError;
1567
1568    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1569        match value {
1570            PostgresValue::Inet(net) => Ok(net),
1571            _ => Err(DrizzleError::ConversionError(
1572                format!("Cannot convert {value:?} to IpInet").into(),
1573            )),
1574        }
1575    }
1576}
1577
1578#[cfg(feature = "cidr")]
1579impl<'a> TryFrom<PostgresValue<'a>> for IpCidr {
1580    type Error = DrizzleError;
1581
1582    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1583        match value {
1584            PostgresValue::Cidr(net) => Ok(net),
1585            _ => Err(DrizzleError::ConversionError(
1586                format!("Cannot convert {value:?} to IpCidr").into(),
1587            )),
1588        }
1589    }
1590}
1591
1592#[cfg(feature = "cidr")]
1593impl<'a> TryFrom<PostgresValue<'a>> for [u8; 6] {
1594    type Error = DrizzleError;
1595
1596    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1597        match value {
1598            PostgresValue::MacAddr(mac) => Ok(mac),
1599            _ => Err(DrizzleError::ConversionError(
1600                format!("Cannot convert {value:?} to [u8; 6]").into(),
1601            )),
1602        }
1603    }
1604}
1605
1606#[cfg(feature = "cidr")]
1607impl<'a> TryFrom<PostgresValue<'a>> for [u8; 8] {
1608    type Error = DrizzleError;
1609
1610    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1611        match value {
1612            PostgresValue::MacAddr8(mac) => Ok(mac),
1613            _ => Err(DrizzleError::ConversionError(
1614                format!("Cannot convert {value:?} to [u8; 8]").into(),
1615            )),
1616        }
1617    }
1618}
1619
1620// --- Geometric TryFrom implementations ---
1621
1622#[cfg(feature = "geo-types")]
1623impl<'a> TryFrom<PostgresValue<'a>> for Point<f64> {
1624    type Error = DrizzleError;
1625
1626    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1627        match value {
1628            PostgresValue::Point(point) => Ok(point),
1629            _ => Err(DrizzleError::ConversionError(
1630                format!("Cannot convert {value:?} to Point").into(),
1631            )),
1632        }
1633    }
1634}
1635
1636#[cfg(feature = "geo-types")]
1637impl<'a> TryFrom<PostgresValue<'a>> for LineString<f64> {
1638    type Error = DrizzleError;
1639
1640    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1641        match value {
1642            PostgresValue::LineString(line) => Ok(line),
1643            _ => Err(DrizzleError::ConversionError(
1644                format!("Cannot convert {value:?} to LineString").into(),
1645            )),
1646        }
1647    }
1648}
1649
1650#[cfg(feature = "geo-types")]
1651impl<'a> TryFrom<PostgresValue<'a>> for Rect<f64> {
1652    type Error = DrizzleError;
1653
1654    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1655        match value {
1656            PostgresValue::Rect(rect) => Ok(rect),
1657            _ => Err(DrizzleError::ConversionError(
1658                format!("Cannot convert {value:?} to Rect").into(),
1659            )),
1660        }
1661    }
1662}
1663
1664// --- Bit String TryFrom implementations ---
1665
1666#[cfg(feature = "bit-vec")]
1667impl<'a> TryFrom<PostgresValue<'a>> for BitVec {
1668    type Error = DrizzleError;
1669
1670    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1671        match value {
1672            PostgresValue::BitVec(bv) => Ok(bv),
1673            _ => Err(DrizzleError::ConversionError(
1674                format!("Cannot convert {value:?} to BitVec").into(),
1675            )),
1676        }
1677    }
1678}
1679
1680// --- ArrayVec TryFrom implementations ---
1681
1682#[cfg(feature = "arrayvec")]
1683impl<'a, const N: usize> TryFrom<PostgresValue<'a>> for arrayvec::ArrayString<N> {
1684    type Error = DrizzleError;
1685
1686    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1687        match value {
1688            PostgresValue::Text(cow_str) => Self::from(cow_str.as_ref()).map_err(|_| {
1689                DrizzleError::ConversionError(
1690                    format!(
1691                        "Text length {} exceeds ArrayString capacity {}",
1692                        cow_str.len(),
1693                        N
1694                    )
1695                    .into(),
1696                )
1697            }),
1698            _ => Err(DrizzleError::ConversionError(
1699                format!("Cannot convert {value:?} to ArrayString").into(),
1700            )),
1701        }
1702    }
1703}
1704
1705#[cfg(feature = "arrayvec")]
1706impl<'a, const N: usize> TryFrom<PostgresValue<'a>> for arrayvec::ArrayVec<u8, N> {
1707    type Error = DrizzleError;
1708
1709    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1710        match value {
1711            PostgresValue::Bytea(cow_bytes) => Self::try_from(cow_bytes.as_ref()).map_err(|_| {
1712                DrizzleError::ConversionError(
1713                    format!(
1714                        "Bytea length {} exceeds ArrayVec capacity {}",
1715                        cow_bytes.len(),
1716                        N
1717                    )
1718                    .into(),
1719                )
1720            }),
1721            _ => Err(DrizzleError::ConversionError(
1722                format!("Cannot convert {value:?} to ArrayVec<u8>").into(),
1723            )),
1724        }
1725    }
1726}
1727
1728// --- Array TryFrom implementations ---
1729
1730impl<'a> TryFrom<PostgresValue<'a>> for Vec<PostgresValue<'a>> {
1731    type Error = DrizzleError;
1732
1733    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1734        match value {
1735            PostgresValue::Array(arr) => Ok(arr),
1736            _ => Err(DrizzleError::ConversionError(
1737                format!("Cannot convert {value:?} to Vec<PostgresValue>").into(),
1738            )),
1739        }
1740    }
1741}
1742
1743impl<'a> TryFrom<&'a PostgresValue<'a>> for &'a [PostgresValue<'a>] {
1744    type Error = DrizzleError;
1745
1746    fn try_from(value: &'a PostgresValue<'a>) -> Result<Self, Self::Error> {
1747        match value {
1748            PostgresValue::Array(arr) => Ok(arr),
1749            _ => Err(DrizzleError::ConversionError(
1750                format!("Cannot convert {value:?} to &[PostgresValue]").into(),
1751            )),
1752        }
1753    }
1754}