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// --- [u8; N] ---
413
414impl<const N: usize> From<[u8; N]> for PostgresValue<'_> {
415    fn from(value: [u8; N]) -> Self {
416        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
417    }
418}
419
420impl<'a, const N: usize> From<&'a [u8; N]> for PostgresValue<'a> {
421    fn from(value: &'a [u8; N]) -> Self {
422        PostgresValue::Bytea(Cow::Borrowed(value))
423    }
424}
425
426// --- ArrayVec<u8, N> ---
427
428#[cfg(feature = "arrayvec")]
429impl<const N: usize> From<arrayvec::ArrayVec<u8, N>> for PostgresValue<'_> {
430    fn from(value: arrayvec::ArrayVec<u8, N>) -> Self {
431        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
432    }
433}
434
435#[cfg(feature = "arrayvec")]
436impl<const N: usize> From<&arrayvec::ArrayVec<u8, N>> for PostgresValue<'_> {
437    fn from(value: &arrayvec::ArrayVec<u8, N>) -> Self {
438        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
439    }
440}
441
442#[cfg(feature = "bytes")]
443impl From<bytes::Bytes> for PostgresValue<'_> {
444    fn from(value: bytes::Bytes) -> Self {
445        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
446    }
447}
448
449#[cfg(feature = "bytes")]
450impl<'a> From<&'a bytes::Bytes> for PostgresValue<'a> {
451    fn from(value: &'a bytes::Bytes) -> Self {
452        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
453    }
454}
455
456#[cfg(feature = "bytes")]
457impl From<bytes::BytesMut> for PostgresValue<'_> {
458    fn from(value: bytes::BytesMut) -> Self {
459        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
460    }
461}
462
463#[cfg(feature = "bytes")]
464impl<'a> From<&'a bytes::BytesMut> for PostgresValue<'a> {
465    fn from(value: &'a bytes::BytesMut) -> Self {
466        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
467    }
468}
469
470#[cfg(feature = "smallvec")]
471impl<const N: usize> From<smallvec::SmallVec<[u8; N]>> for PostgresValue<'_> {
472    fn from(value: smallvec::SmallVec<[u8; N]>) -> Self {
473        PostgresValue::Bytea(Cow::Owned(value.into_vec()))
474    }
475}
476
477#[cfg(feature = "smallvec")]
478impl<const N: usize> From<&smallvec::SmallVec<[u8; N]>> for PostgresValue<'_> {
479    fn from(value: &smallvec::SmallVec<[u8; N]>) -> Self {
480        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
481    }
482}
483
484// --- UUID ---
485
486#[cfg(feature = "uuid")]
487impl From<Uuid> for PostgresValue<'_> {
488    fn from(value: Uuid) -> Self {
489        PostgresValue::Uuid(value)
490    }
491}
492
493#[cfg(feature = "uuid")]
494impl<'a> From<&'a Uuid> for PostgresValue<'a> {
495    fn from(value: &'a Uuid) -> Self {
496        PostgresValue::Uuid(*value)
497    }
498}
499
500// --- JSON ---
501
502#[cfg(feature = "serde")]
503impl From<serde_json::Value> for PostgresValue<'_> {
504    fn from(value: serde_json::Value) -> Self {
505        PostgresValue::Json(value)
506    }
507}
508
509#[cfg(feature = "serde")]
510impl<'a> From<&'a serde_json::Value> for PostgresValue<'a> {
511    fn from(value: &'a serde_json::Value) -> Self {
512        PostgresValue::Json(value.clone())
513    }
514}
515
516// --- Date/Time Types ---
517
518#[cfg(feature = "chrono")]
519impl From<NaiveDate> for PostgresValue<'_> {
520    fn from(value: NaiveDate) -> Self {
521        PostgresValue::Date(value)
522    }
523}
524
525#[cfg(feature = "chrono")]
526impl<'a> From<&'a NaiveDate> for PostgresValue<'a> {
527    fn from(value: &'a NaiveDate) -> Self {
528        PostgresValue::Date(*value)
529    }
530}
531
532#[cfg(feature = "chrono")]
533impl From<NaiveTime> for PostgresValue<'_> {
534    fn from(value: NaiveTime) -> Self {
535        PostgresValue::Time(value)
536    }
537}
538
539#[cfg(feature = "chrono")]
540impl<'a> From<&'a NaiveTime> for PostgresValue<'a> {
541    fn from(value: &'a NaiveTime) -> Self {
542        PostgresValue::Time(*value)
543    }
544}
545
546#[cfg(feature = "chrono")]
547impl From<NaiveDateTime> for PostgresValue<'_> {
548    fn from(value: NaiveDateTime) -> Self {
549        PostgresValue::Timestamp(value)
550    }
551}
552
553#[cfg(feature = "chrono")]
554impl<'a> From<&'a NaiveDateTime> for PostgresValue<'a> {
555    fn from(value: &'a NaiveDateTime) -> Self {
556        PostgresValue::Timestamp(*value)
557    }
558}
559
560#[cfg(feature = "chrono")]
561impl From<DateTime<FixedOffset>> for PostgresValue<'_> {
562    fn from(value: DateTime<FixedOffset>) -> Self {
563        PostgresValue::TimestampTz(value)
564    }
565}
566
567#[cfg(feature = "chrono")]
568impl<'a> From<&'a DateTime<FixedOffset>> for PostgresValue<'a> {
569    fn from(value: &'a DateTime<FixedOffset>) -> Self {
570        PostgresValue::TimestampTz(*value)
571    }
572}
573
574#[cfg(feature = "chrono")]
575impl From<DateTime<Utc>> for PostgresValue<'_> {
576    fn from(value: DateTime<Utc>) -> Self {
577        PostgresValue::TimestampTz(value.into())
578    }
579}
580
581#[cfg(feature = "chrono")]
582impl<'a> From<&'a DateTime<Utc>> for PostgresValue<'a> {
583    fn from(value: &'a DateTime<Utc>) -> Self {
584        PostgresValue::TimestampTz((*value).into())
585    }
586}
587
588#[cfg(feature = "chrono")]
589impl From<Duration> for PostgresValue<'_> {
590    fn from(value: Duration) -> Self {
591        PostgresValue::Interval(value)
592    }
593}
594
595#[cfg(feature = "chrono")]
596impl<'a> From<&'a Duration> for PostgresValue<'a> {
597    fn from(value: &'a Duration) -> Self {
598        PostgresValue::Interval(*value)
599    }
600}
601
602// --- Date/Time Types (time crate) ---
603
604#[cfg(feature = "time")]
605impl From<TimeDate> for PostgresValue<'_> {
606    fn from(value: TimeDate) -> Self {
607        PostgresValue::TimeDate(value)
608    }
609}
610
611#[cfg(feature = "time")]
612impl<'a> From<&'a TimeDate> for PostgresValue<'a> {
613    fn from(value: &'a TimeDate) -> Self {
614        PostgresValue::TimeDate(*value)
615    }
616}
617
618#[cfg(feature = "time")]
619impl From<TimeTime> for PostgresValue<'_> {
620    fn from(value: TimeTime) -> Self {
621        PostgresValue::TimeTime(value)
622    }
623}
624
625#[cfg(feature = "time")]
626impl<'a> From<&'a TimeTime> for PostgresValue<'a> {
627    fn from(value: &'a TimeTime) -> Self {
628        PostgresValue::TimeTime(*value)
629    }
630}
631
632#[cfg(feature = "time")]
633impl From<PrimitiveDateTime> for PostgresValue<'_> {
634    fn from(value: PrimitiveDateTime) -> Self {
635        PostgresValue::TimeTimestamp(value)
636    }
637}
638
639#[cfg(feature = "time")]
640impl<'a> From<&'a PrimitiveDateTime> for PostgresValue<'a> {
641    fn from(value: &'a PrimitiveDateTime) -> Self {
642        PostgresValue::TimeTimestamp(*value)
643    }
644}
645
646#[cfg(feature = "time")]
647impl From<OffsetDateTime> for PostgresValue<'_> {
648    fn from(value: OffsetDateTime) -> Self {
649        PostgresValue::TimeTimestampTz(value)
650    }
651}
652
653#[cfg(feature = "time")]
654impl<'a> From<&'a OffsetDateTime> for PostgresValue<'a> {
655    fn from(value: &'a OffsetDateTime) -> Self {
656        PostgresValue::TimeTimestampTz(*value)
657    }
658}
659
660#[cfg(feature = "time")]
661impl From<TimeDuration> for PostgresValue<'_> {
662    fn from(value: TimeDuration) -> Self {
663        PostgresValue::TimeInterval(value)
664    }
665}
666
667#[cfg(feature = "time")]
668impl<'a> From<&'a TimeDuration> for PostgresValue<'a> {
669    fn from(value: &'a TimeDuration) -> Self {
670        PostgresValue::TimeInterval(*value)
671    }
672}
673
674#[cfg(feature = "jiff")]
675impl From<JiffDate> for PostgresValue<'_> {
676    fn from(value: JiffDate) -> Self {
677        PostgresValue::JiffDate(value)
678    }
679}
680
681#[cfg(feature = "jiff")]
682impl<'a> From<&'a JiffDate> for PostgresValue<'a> {
683    fn from(value: &'a JiffDate) -> Self {
684        PostgresValue::JiffDate(*value)
685    }
686}
687
688#[cfg(feature = "jiff")]
689impl From<JiffTime> for PostgresValue<'_> {
690    fn from(value: JiffTime) -> Self {
691        PostgresValue::JiffTime(value)
692    }
693}
694
695#[cfg(feature = "jiff")]
696impl<'a> From<&'a JiffTime> for PostgresValue<'a> {
697    fn from(value: &'a JiffTime) -> Self {
698        PostgresValue::JiffTime(*value)
699    }
700}
701
702#[cfg(feature = "jiff")]
703impl From<JiffDateTime> for PostgresValue<'_> {
704    fn from(value: JiffDateTime) -> Self {
705        PostgresValue::JiffDateTime(value)
706    }
707}
708
709#[cfg(feature = "jiff")]
710impl<'a> From<&'a JiffDateTime> for PostgresValue<'a> {
711    fn from(value: &'a JiffDateTime) -> Self {
712        PostgresValue::JiffDateTime(*value)
713    }
714}
715
716#[cfg(feature = "jiff")]
717impl From<JiffTimestamp> for PostgresValue<'_> {
718    fn from(value: JiffTimestamp) -> Self {
719        PostgresValue::JiffTimestamp(value)
720    }
721}
722
723#[cfg(feature = "jiff")]
724impl<'a> From<&'a JiffTimestamp> for PostgresValue<'a> {
725    fn from(value: &'a JiffTimestamp) -> Self {
726        PostgresValue::JiffTimestamp(*value)
727    }
728}
729
730// --- Network Address Types ---
731
732#[cfg(feature = "cidr")]
733impl From<IpInet> for PostgresValue<'_> {
734    fn from(value: IpInet) -> Self {
735        PostgresValue::Inet(value)
736    }
737}
738
739#[cfg(feature = "cidr")]
740impl<'a> From<&'a IpInet> for PostgresValue<'a> {
741    fn from(value: &'a IpInet) -> Self {
742        PostgresValue::Inet(*value)
743    }
744}
745
746#[cfg(feature = "cidr")]
747impl From<IpCidr> for PostgresValue<'_> {
748    fn from(value: IpCidr) -> Self {
749        PostgresValue::Cidr(value)
750    }
751}
752
753#[cfg(feature = "cidr")]
754impl<'a> From<&'a IpCidr> for PostgresValue<'a> {
755    fn from(value: &'a IpCidr) -> Self {
756        PostgresValue::Cidr(*value)
757    }
758}
759
760// --- Geometric Types ---
761
762#[cfg(feature = "geo-types")]
763impl From<Point<f64>> for PostgresValue<'_> {
764    fn from(value: Point<f64>) -> Self {
765        PostgresValue::Point(value)
766    }
767}
768
769#[cfg(feature = "geo-types")]
770impl<'a> From<&'a Point<f64>> for PostgresValue<'a> {
771    fn from(value: &'a Point<f64>) -> Self {
772        PostgresValue::Point(*value)
773    }
774}
775
776#[cfg(feature = "geo-types")]
777impl From<LineString<f64>> for PostgresValue<'_> {
778    fn from(value: LineString<f64>) -> Self {
779        PostgresValue::LineString(value)
780    }
781}
782
783#[cfg(feature = "geo-types")]
784impl<'a> From<&'a LineString<f64>> for PostgresValue<'a> {
785    fn from(value: &'a LineString<f64>) -> Self {
786        PostgresValue::LineString(value.clone())
787    }
788}
789
790#[cfg(feature = "geo-types")]
791impl From<Rect<f64>> for PostgresValue<'_> {
792    fn from(value: Rect<f64>) -> Self {
793        PostgresValue::Rect(value)
794    }
795}
796
797#[cfg(feature = "geo-types")]
798impl<'a> From<&'a Rect<f64>> for PostgresValue<'a> {
799    fn from(value: &'a Rect<f64>) -> Self {
800        PostgresValue::Rect(*value)
801    }
802}
803
804// --- Bit String Types ---
805
806#[cfg(feature = "bit-vec")]
807impl From<BitVec> for PostgresValue<'_> {
808    fn from(value: BitVec) -> Self {
809        PostgresValue::BitVec(value)
810    }
811}
812
813#[cfg(feature = "bit-vec")]
814impl<'a> From<&'a BitVec> for PostgresValue<'a> {
815    fn from(value: &'a BitVec) -> Self {
816        PostgresValue::BitVec(value.clone())
817    }
818}
819
820// --- Array Types ---
821
822impl From<Vec<Self>> for PostgresValue<'_> {
823    fn from(value: Vec<Self>) -> Self {
824        PostgresValue::Array(value)
825    }
826}
827
828impl<'a> From<&'a [Self]> for PostgresValue<'a> {
829    fn from(value: &'a [Self]) -> Self {
830        PostgresValue::Array(value.to_vec())
831    }
832}
833
834impl From<Vec<String>> for PostgresValue<'_> {
835    fn from(value: Vec<String>) -> Self {
836        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
837    }
838}
839
840impl<'a> From<Vec<&'a str>> for PostgresValue<'a> {
841    fn from(value: Vec<&'a str>) -> Self {
842        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
843    }
844}
845
846impl From<Vec<i16>> for PostgresValue<'_> {
847    fn from(value: Vec<i16>) -> Self {
848        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
849    }
850}
851
852impl From<Vec<i32>> for PostgresValue<'_> {
853    fn from(value: Vec<i32>) -> Self {
854        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
855    }
856}
857
858impl From<Vec<i64>> for PostgresValue<'_> {
859    fn from(value: Vec<i64>) -> Self {
860        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
861    }
862}
863
864impl From<Vec<f32>> for PostgresValue<'_> {
865    fn from(value: Vec<f32>) -> Self {
866        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
867    }
868}
869
870impl From<Vec<f64>> for PostgresValue<'_> {
871    fn from(value: Vec<f64>) -> Self {
872        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
873    }
874}
875
876impl From<Vec<bool>> for PostgresValue<'_> {
877    fn from(value: Vec<bool>) -> Self {
878        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
879    }
880}
881
882// --- Extended Array Types ---
883
884#[cfg(feature = "uuid")]
885impl From<Vec<uuid::Uuid>> for PostgresValue<'_> {
886    fn from(value: Vec<uuid::Uuid>) -> Self {
887        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
888    }
889}
890
891#[cfg(feature = "chrono")]
892impl From<Vec<NaiveDate>> for PostgresValue<'_> {
893    fn from(value: Vec<NaiveDate>) -> Self {
894        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
895    }
896}
897
898#[cfg(feature = "chrono")]
899impl From<Vec<NaiveTime>> for PostgresValue<'_> {
900    fn from(value: Vec<NaiveTime>) -> Self {
901        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
902    }
903}
904
905#[cfg(feature = "chrono")]
906impl From<Vec<NaiveDateTime>> for PostgresValue<'_> {
907    fn from(value: Vec<NaiveDateTime>) -> Self {
908        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
909    }
910}
911
912#[cfg(feature = "chrono")]
913impl From<Vec<DateTime<Utc>>> for PostgresValue<'_> {
914    fn from(value: Vec<DateTime<Utc>>) -> Self {
915        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
916    }
917}
918
919#[cfg(feature = "rust-decimal")]
920impl From<Vec<Decimal>> for PostgresValue<'_> {
921    fn from(value: Vec<Decimal>) -> Self {
922        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
923    }
924}
925
926// --- Option Types ---
927/// `None` is NULL.
928///
929/// # Panics
930///
931/// Panics when `T`'s conversion fails (for example a JSON payload whose
932/// `Serialize` implementation errors), rather than storing NULL in place of
933/// the value.
934impl<T> From<Option<T>> for PostgresValue<'_>
935where
936    T: TryInto<Self>,
937{
938    fn from(value: Option<T>) -> Self {
939        value.map_or(PostgresValue::Null, |v| {
940            v.try_into().unwrap_or_else(|_| {
941                panic!(
942                    "could not convert a `{}` to a PostgreSQL value",
943                    core::any::type_name::<T>()
944                )
945            })
946        })
947    }
948}
949
950//------------------------------------------------------------------------------
951// TryFrom<PostgresValue> implementations
952//------------------------------------------------------------------------------
953
954// --- Integer Types ---
955
956impl<'a> TryFrom<PostgresValue<'a>> for i16 {
957    type Error = DrizzleError;
958
959    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
960        match value {
961            PostgresValue::Smallint(i) => Ok(i),
962            PostgresValue::Integer(i) => Ok(i.try_into()?),
963            PostgresValue::Bigint(i) => Ok(i.try_into()?),
964            _ => Err(DrizzleError::ConversionError(
965                format!("Cannot convert {value:?} to i16").into(),
966            )),
967        }
968    }
969}
970
971impl<'a> TryFrom<PostgresValue<'a>> for i32 {
972    type Error = DrizzleError;
973
974    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
975        match value {
976            PostgresValue::Smallint(i) => Ok(i.into()),
977            PostgresValue::Integer(i) => Ok(i),
978            PostgresValue::Bigint(i) => Ok(i.try_into()?),
979            _ => Err(DrizzleError::ConversionError(
980                format!("Cannot convert {value:?} to i32").into(),
981            )),
982        }
983    }
984}
985
986impl<'a> TryFrom<PostgresValue<'a>> for i64 {
987    type Error = DrizzleError;
988
989    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
990        match value {
991            PostgresValue::Smallint(i) => Ok(i.into()),
992            PostgresValue::Integer(i) => Ok(i.into()),
993            PostgresValue::Bigint(i) => Ok(i),
994            _ => Err(DrizzleError::ConversionError(
995                format!("Cannot convert {value:?} to i64").into(),
996            )),
997        }
998    }
999}
1000
1001// --- Floating Point Types ---
1002
1003impl<'a> TryFrom<PostgresValue<'a>> for f32 {
1004    type Error = DrizzleError;
1005
1006    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1007        fn parse_float<N: core::fmt::Display>(value: N) -> Result<f32, DrizzleError> {
1008            let s = format!("{value}");
1009            s.parse::<f32>().map_err(|e| {
1010                DrizzleError::ConversionError(format!("Failed to convert {s} to f32: {e}").into())
1011            })
1012        }
1013
1014        match value {
1015            PostgresValue::Real(f) => Ok(f),
1016            PostgresValue::DoublePrecision(f) => parse_float(f),
1017            PostgresValue::Smallint(i) => Ok(Self::from(i)),
1018            PostgresValue::Integer(i) => parse_float(i),
1019            PostgresValue::Bigint(i) => parse_float(i),
1020            _ => Err(DrizzleError::ConversionError(
1021                format!("Cannot convert {value:?} to f32").into(),
1022            )),
1023        }
1024    }
1025}
1026
1027impl<'a> TryFrom<PostgresValue<'a>> for f64 {
1028    type Error = DrizzleError;
1029
1030    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1031        match value {
1032            PostgresValue::Real(f) => Ok(Self::from(f)),
1033            PostgresValue::DoublePrecision(f) => Ok(f),
1034            PostgresValue::Smallint(i) => Ok(Self::from(i)),
1035            PostgresValue::Integer(i) => Ok(Self::from(i)),
1036            PostgresValue::Bigint(i) => {
1037                let s = format!("{i}");
1038                s.parse::<Self>().map_err(|e| {
1039                    DrizzleError::ConversionError(
1040                        format!("Failed to convert {s} to f64: {e}").into(),
1041                    )
1042                })
1043            }
1044            _ => Err(DrizzleError::ConversionError(
1045                format!("Cannot convert {value:?} to f64").into(),
1046            )),
1047        }
1048    }
1049}
1050
1051#[cfg(feature = "rust-decimal")]
1052impl<'a> TryFrom<PostgresValue<'a>> for Decimal {
1053    type Error = DrizzleError;
1054
1055    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1056        match value {
1057            PostgresValue::Numeric(d) => Ok(d),
1058            PostgresValue::Text(cow) => Self::from_str_exact(cow.as_ref()).map_err(|e| {
1059                DrizzleError::ConversionError(format!("Failed to parse DECIMAL: {e}").into())
1060            }),
1061            _ => Err(DrizzleError::ConversionError(
1062                format!("Cannot convert {value:?} to Decimal").into(),
1063            )),
1064        }
1065    }
1066}
1067
1068#[cfg(feature = "rust-decimal")]
1069impl<'a> TryFrom<&'a PostgresValue<'a>> for Decimal {
1070    type Error = DrizzleError;
1071
1072    fn try_from(value: &'a PostgresValue<'a>) -> Result<Self, Self::Error> {
1073        match value {
1074            PostgresValue::Numeric(d) => Ok(*d),
1075            PostgresValue::Text(cow) => Self::from_str_exact(cow.as_ref()).map_err(|e| {
1076                DrizzleError::ConversionError(format!("Failed to parse DECIMAL: {e}").into())
1077            }),
1078            _ => Err(DrizzleError::ConversionError(
1079                format!("Cannot convert {value:?} to Decimal").into(),
1080            )),
1081        }
1082    }
1083}
1084
1085// --- Boolean ---
1086
1087impl<'a> TryFrom<PostgresValue<'a>> for bool {
1088    type Error = DrizzleError;
1089
1090    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1091        match value {
1092            PostgresValue::Boolean(b) => Ok(b),
1093            _ => Err(DrizzleError::ConversionError(
1094                format!("Cannot convert {value:?} to bool").into(),
1095            )),
1096        }
1097    }
1098}
1099
1100// --- String Types ---
1101
1102impl<'a> TryFrom<PostgresValue<'a>> for String {
1103    type Error = DrizzleError;
1104
1105    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1106        match value {
1107            PostgresValue::Text(cow) => Ok(cow.into_owned()),
1108            _ => Err(DrizzleError::ConversionError(
1109                format!("Cannot convert {value:?} to String").into(),
1110            )),
1111        }
1112    }
1113}
1114
1115impl<'a> TryFrom<PostgresValue<'a>> for Box<String> {
1116    type Error = DrizzleError;
1117
1118    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1119        String::try_from(value).map(Self::new)
1120    }
1121}
1122
1123impl<'a> TryFrom<PostgresValue<'a>> for Rc<String> {
1124    type Error = DrizzleError;
1125
1126    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1127        String::try_from(value).map(Self::new)
1128    }
1129}
1130
1131impl<'a> TryFrom<PostgresValue<'a>> for Arc<String> {
1132    type Error = DrizzleError;
1133
1134    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1135        String::try_from(value).map(Self::new)
1136    }
1137}
1138
1139impl<'a> TryFrom<PostgresValue<'a>> for Box<str> {
1140    type Error = DrizzleError;
1141
1142    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1143        match value {
1144            PostgresValue::Text(cow) => Ok(cow.into_owned().into_boxed_str()),
1145            _ => Err(DrizzleError::ConversionError(
1146                format!("Cannot convert {value:?} to Box<str>").into(),
1147            )),
1148        }
1149    }
1150}
1151
1152impl<'a> TryFrom<PostgresValue<'a>> for Rc<str> {
1153    type Error = DrizzleError;
1154
1155    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1156        match value {
1157            PostgresValue::Text(cow) => Ok(Self::from(cow.into_owned())),
1158            _ => Err(DrizzleError::ConversionError(
1159                format!("Cannot convert {value:?} to Rc<str>").into(),
1160            )),
1161        }
1162    }
1163}
1164
1165impl<'a> TryFrom<PostgresValue<'a>> for Arc<str> {
1166    type Error = DrizzleError;
1167
1168    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1169        match value {
1170            PostgresValue::Text(cow) => Ok(Self::from(cow.into_owned())),
1171            _ => Err(DrizzleError::ConversionError(
1172                format!("Cannot convert {value:?} to Arc<str>").into(),
1173            )),
1174        }
1175    }
1176}
1177
1178#[cfg(feature = "compact-str")]
1179impl<'a> TryFrom<PostgresValue<'a>> for compact_str::CompactString {
1180    type Error = DrizzleError;
1181
1182    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1183        String::try_from(value).map(Self::new)
1184    }
1185}
1186
1187// --- Binary Data ---
1188
1189impl<'a> TryFrom<PostgresValue<'a>> for Vec<u8> {
1190    type Error = DrizzleError;
1191
1192    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1193        match value {
1194            PostgresValue::Bytea(cow) => Ok(cow.into_owned()),
1195            _ => Err(DrizzleError::ConversionError(
1196                format!("Cannot convert {value:?} to Vec<u8>").into(),
1197            )),
1198        }
1199    }
1200}
1201
1202impl<'a> TryFrom<PostgresValue<'a>> for Box<Vec<u8>> {
1203    type Error = DrizzleError;
1204
1205    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1206        Vec::<u8>::try_from(value).map(Self::new)
1207    }
1208}
1209
1210impl<'a> TryFrom<PostgresValue<'a>> for Rc<Vec<u8>> {
1211    type Error = DrizzleError;
1212
1213    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1214        Vec::<u8>::try_from(value).map(Self::new)
1215    }
1216}
1217
1218impl<'a> TryFrom<PostgresValue<'a>> for Arc<Vec<u8>> {
1219    type Error = DrizzleError;
1220
1221    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1222        Vec::<u8>::try_from(value).map(Self::new)
1223    }
1224}
1225
1226#[cfg(feature = "bytes")]
1227impl<'a> TryFrom<PostgresValue<'a>> for bytes::Bytes {
1228    type Error = DrizzleError;
1229
1230    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1231        Vec::<u8>::try_from(value).map(Self::from)
1232    }
1233}
1234
1235#[cfg(feature = "bytes")]
1236impl<'a> TryFrom<PostgresValue<'a>> for bytes::BytesMut {
1237    type Error = DrizzleError;
1238
1239    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1240        Vec::<u8>::try_from(value).map(|v| Self::from(v.as_slice()))
1241    }
1242}
1243
1244#[cfg(feature = "smallvec")]
1245impl<'a, const N: usize> TryFrom<PostgresValue<'a>> for smallvec::SmallVec<[u8; N]> {
1246    type Error = DrizzleError;
1247
1248    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1249        Vec::<u8>::try_from(value).map(|v| {
1250            let mut out = Self::new();
1251            out.extend_from_slice(&v);
1252            out
1253        })
1254    }
1255}
1256
1257impl<'a> TryFrom<&'a PostgresValue<'a>> for &'a str {
1258    type Error = DrizzleError;
1259
1260    fn try_from(value: &'a PostgresValue<'a>) -> Result<Self, Self::Error> {
1261        match value {
1262            PostgresValue::Text(cow) => Ok(cow.as_ref()),
1263            _ => Err(DrizzleError::ConversionError(
1264                format!("Cannot convert {value:?} to &str").into(),
1265            )),
1266        }
1267    }
1268}
1269
1270impl<'a> TryFrom<&'a PostgresValue<'a>> for &'a [u8] {
1271    type Error = DrizzleError;
1272
1273    fn try_from(value: &'a PostgresValue<'a>) -> Result<Self, Self::Error> {
1274        match value {
1275            PostgresValue::Bytea(cow) => Ok(cow.as_ref()),
1276            _ => Err(DrizzleError::ConversionError(
1277                format!("Cannot convert {value:?} to &[u8]").into(),
1278            )),
1279        }
1280    }
1281}
1282
1283// --- UUID ---
1284
1285#[cfg(feature = "uuid")]
1286impl<'a> TryFrom<PostgresValue<'a>> for Uuid {
1287    type Error = DrizzleError;
1288
1289    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1290        match value {
1291            PostgresValue::Uuid(uuid) => Ok(uuid),
1292            PostgresValue::Text(cow) => Self::parse_str(cow.as_ref()).map_err(|e| {
1293                DrizzleError::ConversionError(format!("Failed to parse UUID: {e}").into())
1294            }),
1295            _ => Err(DrizzleError::ConversionError(
1296                format!("Cannot convert {value:?} to UUID").into(),
1297            )),
1298        }
1299    }
1300}
1301
1302// --- JSON ---
1303
1304#[cfg(feature = "serde")]
1305impl<'a> TryFrom<PostgresValue<'a>> for serde_json::Value {
1306    type Error = DrizzleError;
1307
1308    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1309        match value {
1310            PostgresValue::Json(json) | PostgresValue::Jsonb(json) => Ok(json),
1311            PostgresValue::Text(cow) => serde_json::from_str(cow.as_ref()).map_err(|e| {
1312                DrizzleError::ConversionError(format!("Failed to parse JSON: {e}").into())
1313            }),
1314            _ => Err(DrizzleError::ConversionError(
1315                format!("Cannot convert {value:?} to JSON").into(),
1316            )),
1317        }
1318    }
1319}
1320
1321// --- Date/Time TryFrom implementations ---
1322
1323#[cfg(feature = "chrono")]
1324impl<'a> TryFrom<PostgresValue<'a>> for NaiveDate {
1325    type Error = DrizzleError;
1326
1327    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1328        match value {
1329            PostgresValue::Date(date) => Ok(date),
1330            PostgresValue::Timestamp(ts) => Ok(ts.date()),
1331            PostgresValue::TimestampTz(ts) => Ok(ts.date_naive()),
1332            _ => Err(DrizzleError::ConversionError(
1333                format!("Cannot convert {value:?} to NaiveDate").into(),
1334            )),
1335        }
1336    }
1337}
1338
1339#[cfg(feature = "chrono")]
1340impl<'a> TryFrom<PostgresValue<'a>> for NaiveTime {
1341    type Error = DrizzleError;
1342
1343    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1344        match value {
1345            PostgresValue::Time(time) => Ok(time),
1346            PostgresValue::Timestamp(ts) => Ok(ts.time()),
1347            PostgresValue::TimestampTz(ts) => Ok(ts.time()),
1348            _ => Err(DrizzleError::ConversionError(
1349                format!("Cannot convert {value:?} to NaiveTime").into(),
1350            )),
1351        }
1352    }
1353}
1354
1355#[cfg(feature = "chrono")]
1356impl<'a> TryFrom<PostgresValue<'a>> for NaiveDateTime {
1357    type Error = DrizzleError;
1358
1359    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1360        match value {
1361            PostgresValue::Timestamp(ts) => Ok(ts),
1362            PostgresValue::TimestampTz(ts) => Ok(ts.naive_utc()),
1363            _ => Err(DrizzleError::ConversionError(
1364                format!("Cannot convert {value:?} to NaiveDateTime").into(),
1365            )),
1366        }
1367    }
1368}
1369
1370#[cfg(feature = "chrono")]
1371impl<'a> TryFrom<PostgresValue<'a>> for DateTime<FixedOffset> {
1372    type Error = DrizzleError;
1373
1374    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1375        match value {
1376            PostgresValue::TimestampTz(ts) => Ok(ts),
1377            _ => Err(DrizzleError::ConversionError(
1378                format!("Cannot convert {value:?} to DateTime<FixedOffset>").into(),
1379            )),
1380        }
1381    }
1382}
1383
1384#[cfg(feature = "chrono")]
1385impl<'a> TryFrom<PostgresValue<'a>> for DateTime<Utc> {
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.with_timezone(&Utc)),
1391            _ => Err(DrizzleError::ConversionError(
1392                format!("Cannot convert {value:?} to DateTime<Utc>").into(),
1393            )),
1394        }
1395    }
1396}
1397
1398#[cfg(feature = "chrono")]
1399impl<'a> TryFrom<PostgresValue<'a>> for Duration {
1400    type Error = DrizzleError;
1401
1402    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1403        match value {
1404            PostgresValue::Interval(duration) => Ok(duration),
1405            _ => Err(DrizzleError::ConversionError(
1406                format!("Cannot convert {value:?} to Duration").into(),
1407            )),
1408        }
1409    }
1410}
1411
1412// --- Date/Time TryFrom implementations (time crate) ---
1413
1414#[cfg(feature = "time")]
1415impl<'a> TryFrom<PostgresValue<'a>> for TimeDate {
1416    type Error = DrizzleError;
1417
1418    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1419        match value {
1420            PostgresValue::TimeDate(date) => Ok(date),
1421            PostgresValue::TimeTimestamp(ts) => Ok(ts.date()),
1422            PostgresValue::TimeTimestampTz(ts) => Ok(ts.date()),
1423            _ => Err(DrizzleError::ConversionError(
1424                format!("Cannot convert {value:?} to time::Date").into(),
1425            )),
1426        }
1427    }
1428}
1429
1430#[cfg(feature = "time")]
1431impl<'a> TryFrom<PostgresValue<'a>> for TimeTime {
1432    type Error = DrizzleError;
1433
1434    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1435        match value {
1436            PostgresValue::TimeTime(time) => Ok(time),
1437            PostgresValue::TimeTimestamp(ts) => Ok(ts.time()),
1438            PostgresValue::TimeTimestampTz(ts) => Ok(ts.time()),
1439            _ => Err(DrizzleError::ConversionError(
1440                format!("Cannot convert {value:?} to time::Time").into(),
1441            )),
1442        }
1443    }
1444}
1445
1446#[cfg(feature = "time")]
1447impl<'a> TryFrom<PostgresValue<'a>> for PrimitiveDateTime {
1448    type Error = DrizzleError;
1449
1450    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1451        match value {
1452            PostgresValue::TimeTimestamp(ts) => Ok(ts),
1453            _ => Err(DrizzleError::ConversionError(
1454                format!("Cannot convert {value:?} to time::PrimitiveDateTime").into(),
1455            )),
1456        }
1457    }
1458}
1459
1460#[cfg(feature = "time")]
1461impl<'a> TryFrom<PostgresValue<'a>> for OffsetDateTime {
1462    type Error = DrizzleError;
1463
1464    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1465        match value {
1466            PostgresValue::TimeTimestampTz(ts) => Ok(ts),
1467            _ => Err(DrizzleError::ConversionError(
1468                format!("Cannot convert {value:?} to time::OffsetDateTime").into(),
1469            )),
1470        }
1471    }
1472}
1473
1474#[cfg(feature = "time")]
1475impl<'a> TryFrom<PostgresValue<'a>> for TimeDuration {
1476    type Error = DrizzleError;
1477
1478    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1479        match value {
1480            PostgresValue::TimeInterval(dur) => Ok(dur),
1481            _ => Err(DrizzleError::ConversionError(
1482                format!("Cannot convert {value:?} to time::Duration").into(),
1483            )),
1484        }
1485    }
1486}
1487
1488#[cfg(feature = "jiff")]
1489impl<'a> TryFrom<PostgresValue<'a>> for JiffDate {
1490    type Error = DrizzleError;
1491
1492    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1493        match value {
1494            PostgresValue::JiffDate(date) => Ok(date),
1495            PostgresValue::JiffDateTime(ts) => Ok(ts.date()),
1496            PostgresValue::JiffTimestamp(ts) => Ok(jiff::tz::Offset::UTC.to_datetime(ts).date()),
1497            _ => Err(DrizzleError::ConversionError(
1498                format!("Cannot convert {value:?} to jiff::civil::Date").into(),
1499            )),
1500        }
1501    }
1502}
1503
1504#[cfg(feature = "jiff")]
1505impl<'a> TryFrom<PostgresValue<'a>> for JiffTime {
1506    type Error = DrizzleError;
1507
1508    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1509        match value {
1510            PostgresValue::JiffTime(time) => Ok(time),
1511            PostgresValue::JiffDateTime(ts) => Ok(ts.time()),
1512            PostgresValue::JiffTimestamp(ts) => Ok(jiff::tz::Offset::UTC.to_datetime(ts).time()),
1513            _ => Err(DrizzleError::ConversionError(
1514                format!("Cannot convert {value:?} to jiff::civil::Time").into(),
1515            )),
1516        }
1517    }
1518}
1519
1520#[cfg(feature = "jiff")]
1521impl<'a> TryFrom<PostgresValue<'a>> for JiffDateTime {
1522    type Error = DrizzleError;
1523
1524    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1525        match value {
1526            PostgresValue::JiffDateTime(ts) => Ok(ts),
1527            _ => Err(DrizzleError::ConversionError(
1528                format!("Cannot convert {value:?} to jiff::civil::DateTime").into(),
1529            )),
1530        }
1531    }
1532}
1533
1534#[cfg(feature = "jiff")]
1535impl<'a> TryFrom<PostgresValue<'a>> for JiffTimestamp {
1536    type Error = DrizzleError;
1537
1538    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1539        match value {
1540            PostgresValue::JiffTimestamp(ts) => Ok(ts),
1541            _ => Err(DrizzleError::ConversionError(
1542                format!("Cannot convert {value:?} to jiff::Timestamp").into(),
1543            )),
1544        }
1545    }
1546}
1547
1548// --- Network Address TryFrom implementations ---
1549
1550#[cfg(feature = "cidr")]
1551impl<'a> TryFrom<PostgresValue<'a>> for IpInet {
1552    type Error = DrizzleError;
1553
1554    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1555        match value {
1556            PostgresValue::Inet(net) => Ok(net),
1557            _ => Err(DrizzleError::ConversionError(
1558                format!("Cannot convert {value:?} to IpInet").into(),
1559            )),
1560        }
1561    }
1562}
1563
1564#[cfg(feature = "cidr")]
1565impl<'a> TryFrom<PostgresValue<'a>> for IpCidr {
1566    type Error = DrizzleError;
1567
1568    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1569        match value {
1570            PostgresValue::Cidr(net) => Ok(net),
1571            _ => Err(DrizzleError::ConversionError(
1572                format!("Cannot convert {value:?} to IpCidr").into(),
1573            )),
1574        }
1575    }
1576}
1577
1578// --- Geometric TryFrom implementations ---
1579
1580#[cfg(feature = "geo-types")]
1581impl<'a> TryFrom<PostgresValue<'a>> for Point<f64> {
1582    type Error = DrizzleError;
1583
1584    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1585        match value {
1586            PostgresValue::Point(point) => Ok(point),
1587            _ => Err(DrizzleError::ConversionError(
1588                format!("Cannot convert {value:?} to Point").into(),
1589            )),
1590        }
1591    }
1592}
1593
1594#[cfg(feature = "geo-types")]
1595impl<'a> TryFrom<PostgresValue<'a>> for LineString<f64> {
1596    type Error = DrizzleError;
1597
1598    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1599        match value {
1600            PostgresValue::LineString(line) => Ok(line),
1601            _ => Err(DrizzleError::ConversionError(
1602                format!("Cannot convert {value:?} to LineString").into(),
1603            )),
1604        }
1605    }
1606}
1607
1608#[cfg(feature = "geo-types")]
1609impl<'a> TryFrom<PostgresValue<'a>> for Rect<f64> {
1610    type Error = DrizzleError;
1611
1612    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1613        match value {
1614            PostgresValue::Rect(rect) => Ok(rect),
1615            _ => Err(DrizzleError::ConversionError(
1616                format!("Cannot convert {value:?} to Rect").into(),
1617            )),
1618        }
1619    }
1620}
1621
1622// --- Bit String TryFrom implementations ---
1623
1624#[cfg(feature = "bit-vec")]
1625impl<'a> TryFrom<PostgresValue<'a>> for BitVec {
1626    type Error = DrizzleError;
1627
1628    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1629        match value {
1630            PostgresValue::BitVec(bv) => Ok(bv),
1631            _ => Err(DrizzleError::ConversionError(
1632                format!("Cannot convert {value:?} to BitVec").into(),
1633            )),
1634        }
1635    }
1636}
1637
1638// --- ArrayVec TryFrom implementations ---
1639
1640#[cfg(feature = "arrayvec")]
1641impl<'a, const N: usize> TryFrom<PostgresValue<'a>> for arrayvec::ArrayString<N> {
1642    type Error = DrizzleError;
1643
1644    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1645        match value {
1646            PostgresValue::Text(cow_str) => Self::from(cow_str.as_ref()).map_err(|_| {
1647                DrizzleError::ConversionError(
1648                    format!(
1649                        "Text length {} exceeds ArrayString capacity {}",
1650                        cow_str.len(),
1651                        N
1652                    )
1653                    .into(),
1654                )
1655            }),
1656            _ => Err(DrizzleError::ConversionError(
1657                format!("Cannot convert {value:?} to ArrayString").into(),
1658            )),
1659        }
1660    }
1661}
1662
1663#[cfg(feature = "arrayvec")]
1664impl<'a, const N: usize> TryFrom<PostgresValue<'a>> for arrayvec::ArrayVec<u8, N> {
1665    type Error = DrizzleError;
1666
1667    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1668        match value {
1669            PostgresValue::Bytea(cow_bytes) => Self::try_from(cow_bytes.as_ref()).map_err(|_| {
1670                DrizzleError::ConversionError(
1671                    format!(
1672                        "Bytea length {} exceeds ArrayVec capacity {}",
1673                        cow_bytes.len(),
1674                        N
1675                    )
1676                    .into(),
1677                )
1678            }),
1679            _ => Err(DrizzleError::ConversionError(
1680                format!("Cannot convert {value:?} to ArrayVec<u8>").into(),
1681            )),
1682        }
1683    }
1684}
1685
1686impl<'a, const N: usize> TryFrom<PostgresValue<'a>> for [u8; N] {
1687    type Error = DrizzleError;
1688
1689    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1690        let bytes: &[u8] = match &value {
1691            PostgresValue::Bytea(bytes) => bytes.as_ref(),
1692            #[cfg(feature = "cidr")]
1693            PostgresValue::MacAddr(mac) => mac,
1694            #[cfg(feature = "cidr")]
1695            PostgresValue::MacAddr8(mac) => mac,
1696            _ => {
1697                return Err(DrizzleError::ConversionError(
1698                    format!("Cannot convert {value:?} to [u8; {N}]").into(),
1699                ));
1700            }
1701        };
1702        Self::try_from(bytes).map_err(|_| {
1703            DrizzleError::ConversionError(
1704                format!("expected {N} bytes for [u8; {N}], got {}", bytes.len()).into(),
1705            )
1706        })
1707    }
1708}
1709
1710// --- Array TryFrom implementations ---
1711
1712impl<'a> TryFrom<PostgresValue<'a>> for Vec<PostgresValue<'a>> {
1713    type Error = DrizzleError;
1714
1715    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1716        match value {
1717            PostgresValue::Array(arr) => Ok(arr),
1718            _ => Err(DrizzleError::ConversionError(
1719                format!("Cannot convert {value:?} to Vec<PostgresValue>").into(),
1720            )),
1721        }
1722    }
1723}
1724
1725impl<'a> TryFrom<&'a PostgresValue<'a>> for &'a [PostgresValue<'a>] {
1726    type Error = DrizzleError;
1727
1728    fn try_from(value: &'a PostgresValue<'a>) -> Result<Self, Self::Error> {
1729        match value {
1730            PostgresValue::Array(arr) => Ok(arr),
1731            _ => Err(DrizzleError::ConversionError(
1732                format!("Cannot convert {value:?} to &[PostgresValue]").into(),
1733            )),
1734        }
1735    }
1736}