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