Skip to main content

drizzle_postgres/values/
conversions.rs

1//! From<T> and TryFrom<PostgresValue> implementations
2
3use super::PostgresValue;
4use drizzle_core::error::DrizzleError;
5use std::{borrow::Cow, rc::Rc, sync::Arc};
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 = "cidr")]
14use cidr::{IpCidr, IpInet};
15
16#[cfg(feature = "geo-types")]
17use geo_types::{LineString, Point, Rect};
18
19#[cfg(feature = "bit-vec")]
20use bit_vec::BitVec;
21
22//------------------------------------------------------------------------------
23// From<T> implementations
24//------------------------------------------------------------------------------
25
26// --- Integer Types ---
27
28// i8 → SMALLINT (PostgreSQL doesn't have a native i8 type)
29impl<'a> From<i8> for PostgresValue<'a> {
30    fn from(value: i8) -> Self {
31        PostgresValue::Smallint(value as i16)
32    }
33}
34
35impl<'a> From<&'a i8> for PostgresValue<'a> {
36    fn from(value: &'a i8) -> Self {
37        PostgresValue::Smallint(*value as i16)
38    }
39}
40
41// i16 (SMALLINT)
42impl<'a> From<i16> for PostgresValue<'a> {
43    fn from(value: i16) -> Self {
44        PostgresValue::Smallint(value)
45    }
46}
47
48impl<'a> From<&'a i16> for PostgresValue<'a> {
49    fn from(value: &'a i16) -> Self {
50        PostgresValue::Smallint(*value)
51    }
52}
53
54// i32 (INTEGER)
55impl<'a> From<i32> for PostgresValue<'a> {
56    fn from(value: i32) -> Self {
57        PostgresValue::Integer(value)
58    }
59}
60
61impl<'a> From<&'a i32> for PostgresValue<'a> {
62    fn from(value: &'a i32) -> Self {
63        PostgresValue::Integer(*value)
64    }
65}
66
67// i64 (BIGINT)
68impl<'a> From<i64> for PostgresValue<'a> {
69    fn from(value: i64) -> Self {
70        PostgresValue::Bigint(value)
71    }
72}
73
74impl<'a> From<&'a i64> for PostgresValue<'a> {
75    fn from(value: &'a i64) -> Self {
76        PostgresValue::Bigint(*value)
77    }
78}
79
80// u8 → SMALLINT (PostgreSQL doesn't have unsigned types)
81impl<'a> From<u8> for PostgresValue<'a> {
82    fn from(value: u8) -> Self {
83        PostgresValue::Smallint(value as i16)
84    }
85}
86
87impl<'a> From<&'a u8> for PostgresValue<'a> {
88    fn from(value: &'a u8) -> Self {
89        PostgresValue::Smallint(*value as i16)
90    }
91}
92
93// u16 → INTEGER (cast to larger signed type)
94impl<'a> From<u16> for PostgresValue<'a> {
95    fn from(value: u16) -> Self {
96        PostgresValue::Integer(value as i32)
97    }
98}
99
100impl<'a> From<&'a u16> for PostgresValue<'a> {
101    fn from(value: &'a u16) -> Self {
102        PostgresValue::Integer(*value as i32)
103    }
104}
105
106// u32 → BIGINT (cast to larger signed type since u32 max > i32 max)
107impl<'a> From<u32> for PostgresValue<'a> {
108    fn from(value: u32) -> Self {
109        PostgresValue::Bigint(value as i64)
110    }
111}
112
113impl<'a> From<&'a u32> for PostgresValue<'a> {
114    fn from(value: &'a u32) -> Self {
115        PostgresValue::Bigint(*value as i64)
116    }
117}
118
119// u64 → BIGINT (cast with potential overflow since u64 max > i64 max)
120impl<'a> From<u64> for PostgresValue<'a> {
121    fn from(value: u64) -> Self {
122        PostgresValue::Bigint(value as i64)
123    }
124}
125
126impl<'a> From<&'a u64> for PostgresValue<'a> {
127    fn from(value: &'a u64) -> Self {
128        PostgresValue::Bigint(*value as i64)
129    }
130}
131
132// isize → BIGINT (platform-dependent size)
133impl<'a> From<isize> for PostgresValue<'a> {
134    fn from(value: isize) -> Self {
135        PostgresValue::Bigint(value as i64)
136    }
137}
138
139impl<'a> From<&'a isize> for PostgresValue<'a> {
140    fn from(value: &'a isize) -> Self {
141        PostgresValue::Bigint(*value as i64)
142    }
143}
144
145// usize → BIGINT (platform-dependent size)
146impl<'a> From<usize> for PostgresValue<'a> {
147    fn from(value: usize) -> Self {
148        PostgresValue::Bigint(value as i64)
149    }
150}
151
152impl<'a> From<&'a usize> for PostgresValue<'a> {
153    fn from(value: &'a usize) -> Self {
154        PostgresValue::Bigint(*value as i64)
155    }
156}
157
158// --- Floating Point Types ---
159
160// f32 (REAL)
161impl<'a> From<f32> for PostgresValue<'a> {
162    fn from(value: f32) -> Self {
163        PostgresValue::Real(value)
164    }
165}
166
167impl<'a> From<&'a f32> for PostgresValue<'a> {
168    fn from(value: &'a f32) -> Self {
169        PostgresValue::Real(*value)
170    }
171}
172
173// f64 (DOUBLE PRECISION)
174impl<'a> From<f64> for PostgresValue<'a> {
175    fn from(value: f64) -> Self {
176        PostgresValue::DoublePrecision(value)
177    }
178}
179
180impl<'a> From<&'a f64> for PostgresValue<'a> {
181    fn from(value: &'a f64) -> Self {
182        PostgresValue::DoublePrecision(*value)
183    }
184}
185
186// --- Boolean ---
187
188impl<'a> From<bool> for PostgresValue<'a> {
189    fn from(value: bool) -> Self {
190        PostgresValue::Boolean(value)
191    }
192}
193
194impl<'a> From<&'a bool> for PostgresValue<'a> {
195    fn from(value: &'a bool) -> Self {
196        PostgresValue::Boolean(*value)
197    }
198}
199
200// --- String Types ---
201
202impl<'a> From<&'a str> for PostgresValue<'a> {
203    fn from(value: &'a str) -> Self {
204        PostgresValue::Text(Cow::Borrowed(value))
205    }
206}
207
208impl<'a> From<Cow<'a, str>> for PostgresValue<'a> {
209    fn from(value: Cow<'a, str>) -> Self {
210        PostgresValue::Text(value)
211    }
212}
213
214impl<'a> From<String> for PostgresValue<'a> {
215    fn from(value: String) -> Self {
216        PostgresValue::Text(Cow::Owned(value))
217    }
218}
219
220impl<'a> From<&'a String> for PostgresValue<'a> {
221    fn from(value: &'a String) -> Self {
222        PostgresValue::Text(Cow::Borrowed(value))
223    }
224}
225
226impl<'a> From<Box<String>> for PostgresValue<'a> {
227    fn from(value: Box<String>) -> Self {
228        PostgresValue::Text(Cow::Owned(*value))
229    }
230}
231
232impl<'a> From<&'a Box<String>> for PostgresValue<'a> {
233    fn from(value: &'a Box<String>) -> Self {
234        PostgresValue::Text(Cow::Borrowed(value.as_str()))
235    }
236}
237
238impl<'a> From<Rc<String>> for PostgresValue<'a> {
239    fn from(value: Rc<String>) -> Self {
240        PostgresValue::Text(Cow::Owned(value.as_ref().clone()))
241    }
242}
243
244impl<'a> From<&'a Rc<String>> for PostgresValue<'a> {
245    fn from(value: &'a Rc<String>) -> Self {
246        PostgresValue::Text(Cow::Borrowed(value.as_str()))
247    }
248}
249
250impl<'a> From<Arc<String>> for PostgresValue<'a> {
251    fn from(value: Arc<String>) -> Self {
252        PostgresValue::Text(Cow::Owned(value.as_ref().clone()))
253    }
254}
255
256impl<'a> From<&'a Arc<String>> for PostgresValue<'a> {
257    fn from(value: &'a Arc<String>) -> Self {
258        PostgresValue::Text(Cow::Borrowed(value.as_str()))
259    }
260}
261
262impl<'a> From<Box<str>> for PostgresValue<'a> {
263    fn from(value: Box<str>) -> Self {
264        PostgresValue::Text(Cow::Owned(value.into()))
265    }
266}
267
268impl<'a> From<&'a Box<str>> for PostgresValue<'a> {
269    fn from(value: &'a Box<str>) -> Self {
270        PostgresValue::Text(Cow::Borrowed(value.as_ref()))
271    }
272}
273
274impl<'a> From<Rc<str>> for PostgresValue<'a> {
275    fn from(value: Rc<str>) -> Self {
276        PostgresValue::Text(Cow::Owned(value.as_ref().to_string()))
277    }
278}
279
280impl<'a> From<&'a Rc<str>> for PostgresValue<'a> {
281    fn from(value: &'a Rc<str>) -> Self {
282        PostgresValue::Text(Cow::Borrowed(value.as_ref()))
283    }
284}
285
286impl<'a> From<Arc<str>> for PostgresValue<'a> {
287    fn from(value: Arc<str>) -> Self {
288        PostgresValue::Text(Cow::Owned(value.as_ref().to_string()))
289    }
290}
291
292impl<'a> From<&'a Arc<str>> for PostgresValue<'a> {
293    fn from(value: &'a Arc<str>) -> Self {
294        PostgresValue::Text(Cow::Borrowed(value.as_ref()))
295    }
296}
297
298// --- ArrayString ---
299
300#[cfg(feature = "arrayvec")]
301impl<'a, const N: usize> From<arrayvec::ArrayString<N>> for PostgresValue<'a> {
302    fn from(value: arrayvec::ArrayString<N>) -> Self {
303        PostgresValue::Text(Cow::Owned(value.to_string()))
304    }
305}
306
307#[cfg(feature = "arrayvec")]
308impl<'a, const N: usize> From<&arrayvec::ArrayString<N>> for PostgresValue<'a> {
309    fn from(value: &arrayvec::ArrayString<N>) -> Self {
310        PostgresValue::Text(Cow::Owned(value.as_str().to_owned()))
311    }
312}
313
314// --- Binary Data ---
315
316impl<'a> From<&'a [u8]> for PostgresValue<'a> {
317    fn from(value: &'a [u8]) -> Self {
318        PostgresValue::Bytea(Cow::Borrowed(value))
319    }
320}
321
322impl<'a> From<Cow<'a, [u8]>> for PostgresValue<'a> {
323    fn from(value: Cow<'a, [u8]>) -> Self {
324        PostgresValue::Bytea(value)
325    }
326}
327
328impl<'a> From<Vec<u8>> for PostgresValue<'a> {
329    fn from(value: Vec<u8>) -> Self {
330        PostgresValue::Bytea(Cow::Owned(value))
331    }
332}
333
334impl<'a> From<Box<Vec<u8>>> for PostgresValue<'a> {
335    fn from(value: Box<Vec<u8>>) -> Self {
336        PostgresValue::Bytea(Cow::Owned(*value))
337    }
338}
339
340impl<'a> From<&'a Box<Vec<u8>>> for PostgresValue<'a> {
341    fn from(value: &'a Box<Vec<u8>>) -> Self {
342        PostgresValue::Bytea(Cow::Borrowed(value.as_slice()))
343    }
344}
345
346impl<'a> From<Rc<Vec<u8>>> for PostgresValue<'a> {
347    fn from(value: Rc<Vec<u8>>) -> Self {
348        PostgresValue::Bytea(Cow::Owned(value.as_ref().clone()))
349    }
350}
351
352impl<'a> From<&'a Rc<Vec<u8>>> for PostgresValue<'a> {
353    fn from(value: &'a Rc<Vec<u8>>) -> Self {
354        PostgresValue::Bytea(Cow::Borrowed(value.as_slice()))
355    }
356}
357
358impl<'a> From<Arc<Vec<u8>>> for PostgresValue<'a> {
359    fn from(value: Arc<Vec<u8>>) -> Self {
360        PostgresValue::Bytea(Cow::Owned(value.as_ref().clone()))
361    }
362}
363
364impl<'a> From<&'a Arc<Vec<u8>>> for PostgresValue<'a> {
365    fn from(value: &'a Arc<Vec<u8>>) -> Self {
366        PostgresValue::Bytea(Cow::Borrowed(value.as_slice()))
367    }
368}
369
370// --- ArrayVec<u8, N> ---
371
372#[cfg(feature = "arrayvec")]
373impl<'a, const N: usize> From<arrayvec::ArrayVec<u8, N>> for PostgresValue<'a> {
374    fn from(value: arrayvec::ArrayVec<u8, N>) -> Self {
375        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
376    }
377}
378
379#[cfg(feature = "arrayvec")]
380impl<'a, const N: usize> From<&arrayvec::ArrayVec<u8, N>> for PostgresValue<'a> {
381    fn from(value: &arrayvec::ArrayVec<u8, N>) -> Self {
382        PostgresValue::Bytea(Cow::Owned(value.to_vec()))
383    }
384}
385
386// --- UUID ---
387
388#[cfg(feature = "uuid")]
389impl<'a> From<Uuid> for PostgresValue<'a> {
390    fn from(value: Uuid) -> Self {
391        PostgresValue::Uuid(value)
392    }
393}
394
395#[cfg(feature = "uuid")]
396impl<'a> From<&'a Uuid> for PostgresValue<'a> {
397    fn from(value: &'a Uuid) -> Self {
398        PostgresValue::Uuid(*value)
399    }
400}
401
402// --- JSON ---
403
404#[cfg(feature = "serde")]
405impl<'a> From<serde_json::Value> for PostgresValue<'a> {
406    fn from(value: serde_json::Value) -> Self {
407        PostgresValue::Json(value)
408    }
409}
410
411#[cfg(feature = "serde")]
412impl<'a> From<&'a serde_json::Value> for PostgresValue<'a> {
413    fn from(value: &'a serde_json::Value) -> Self {
414        PostgresValue::Json(value.clone())
415    }
416}
417
418// --- Date/Time Types ---
419
420#[cfg(feature = "chrono")]
421impl<'a> From<NaiveDate> for PostgresValue<'a> {
422    fn from(value: NaiveDate) -> Self {
423        PostgresValue::Date(value)
424    }
425}
426
427#[cfg(feature = "chrono")]
428impl<'a> From<&'a NaiveDate> for PostgresValue<'a> {
429    fn from(value: &'a NaiveDate) -> Self {
430        PostgresValue::Date(*value)
431    }
432}
433
434#[cfg(feature = "chrono")]
435impl<'a> From<NaiveTime> for PostgresValue<'a> {
436    fn from(value: NaiveTime) -> Self {
437        PostgresValue::Time(value)
438    }
439}
440
441#[cfg(feature = "chrono")]
442impl<'a> From<&'a NaiveTime> for PostgresValue<'a> {
443    fn from(value: &'a NaiveTime) -> Self {
444        PostgresValue::Time(*value)
445    }
446}
447
448#[cfg(feature = "chrono")]
449impl<'a> From<NaiveDateTime> for PostgresValue<'a> {
450    fn from(value: NaiveDateTime) -> Self {
451        PostgresValue::Timestamp(value)
452    }
453}
454
455#[cfg(feature = "chrono")]
456impl<'a> From<&'a NaiveDateTime> for PostgresValue<'a> {
457    fn from(value: &'a NaiveDateTime) -> Self {
458        PostgresValue::Timestamp(*value)
459    }
460}
461
462#[cfg(feature = "chrono")]
463impl<'a> From<DateTime<FixedOffset>> for PostgresValue<'a> {
464    fn from(value: DateTime<FixedOffset>) -> Self {
465        PostgresValue::TimestampTz(value)
466    }
467}
468
469#[cfg(feature = "chrono")]
470impl<'a> From<&'a DateTime<FixedOffset>> for PostgresValue<'a> {
471    fn from(value: &'a DateTime<FixedOffset>) -> Self {
472        PostgresValue::TimestampTz(*value)
473    }
474}
475
476#[cfg(feature = "chrono")]
477impl<'a> From<DateTime<Utc>> for PostgresValue<'a> {
478    fn from(value: DateTime<Utc>) -> Self {
479        PostgresValue::TimestampTz(value.into())
480    }
481}
482
483#[cfg(feature = "chrono")]
484impl<'a> From<&'a DateTime<Utc>> for PostgresValue<'a> {
485    fn from(value: &'a DateTime<Utc>) -> Self {
486        PostgresValue::TimestampTz((*value).into())
487    }
488}
489
490#[cfg(feature = "chrono")]
491impl<'a> From<Duration> for PostgresValue<'a> {
492    fn from(value: Duration) -> Self {
493        PostgresValue::Interval(value)
494    }
495}
496
497#[cfg(feature = "chrono")]
498impl<'a> From<&'a Duration> for PostgresValue<'a> {
499    fn from(value: &'a Duration) -> Self {
500        PostgresValue::Interval(*value)
501    }
502}
503
504// --- Network Address Types ---
505
506#[cfg(feature = "cidr")]
507impl<'a> From<IpInet> for PostgresValue<'a> {
508    fn from(value: IpInet) -> Self {
509        PostgresValue::Inet(value)
510    }
511}
512
513#[cfg(feature = "cidr")]
514impl<'a> From<&'a IpInet> for PostgresValue<'a> {
515    fn from(value: &'a IpInet) -> Self {
516        PostgresValue::Inet(*value)
517    }
518}
519
520#[cfg(feature = "cidr")]
521impl<'a> From<IpCidr> for PostgresValue<'a> {
522    fn from(value: IpCidr) -> Self {
523        PostgresValue::Cidr(value)
524    }
525}
526
527#[cfg(feature = "cidr")]
528impl<'a> From<&'a IpCidr> for PostgresValue<'a> {
529    fn from(value: &'a IpCidr) -> Self {
530        PostgresValue::Cidr(*value)
531    }
532}
533
534#[cfg(feature = "cidr")]
535impl<'a> From<[u8; 6]> for PostgresValue<'a> {
536    fn from(value: [u8; 6]) -> Self {
537        PostgresValue::MacAddr(value)
538    }
539}
540
541#[cfg(feature = "cidr")]
542impl<'a> From<&'a [u8; 6]> for PostgresValue<'a> {
543    fn from(value: &'a [u8; 6]) -> Self {
544        PostgresValue::MacAddr(*value)
545    }
546}
547
548#[cfg(feature = "cidr")]
549impl<'a> From<[u8; 8]> for PostgresValue<'a> {
550    fn from(value: [u8; 8]) -> Self {
551        PostgresValue::MacAddr8(value)
552    }
553}
554
555#[cfg(feature = "cidr")]
556impl<'a> From<&'a [u8; 8]> for PostgresValue<'a> {
557    fn from(value: &'a [u8; 8]) -> Self {
558        PostgresValue::MacAddr8(*value)
559    }
560}
561
562// --- Geometric Types ---
563
564#[cfg(feature = "geo-types")]
565impl<'a> From<Point<f64>> for PostgresValue<'a> {
566    fn from(value: Point<f64>) -> Self {
567        PostgresValue::Point(value)
568    }
569}
570
571#[cfg(feature = "geo-types")]
572impl<'a> From<&'a Point<f64>> for PostgresValue<'a> {
573    fn from(value: &'a Point<f64>) -> Self {
574        PostgresValue::Point(*value)
575    }
576}
577
578#[cfg(feature = "geo-types")]
579impl<'a> From<LineString<f64>> for PostgresValue<'a> {
580    fn from(value: LineString<f64>) -> Self {
581        PostgresValue::LineString(value)
582    }
583}
584
585#[cfg(feature = "geo-types")]
586impl<'a> From<&'a LineString<f64>> for PostgresValue<'a> {
587    fn from(value: &'a LineString<f64>) -> Self {
588        PostgresValue::LineString(value.clone())
589    }
590}
591
592#[cfg(feature = "geo-types")]
593impl<'a> From<Rect<f64>> for PostgresValue<'a> {
594    fn from(value: Rect<f64>) -> Self {
595        PostgresValue::Rect(value)
596    }
597}
598
599#[cfg(feature = "geo-types")]
600impl<'a> From<&'a Rect<f64>> for PostgresValue<'a> {
601    fn from(value: &'a Rect<f64>) -> Self {
602        PostgresValue::Rect(*value)
603    }
604}
605
606// --- Bit String Types ---
607
608#[cfg(feature = "bit-vec")]
609impl<'a> From<BitVec> for PostgresValue<'a> {
610    fn from(value: BitVec) -> Self {
611        PostgresValue::BitVec(value)
612    }
613}
614
615#[cfg(feature = "bit-vec")]
616impl<'a> From<&'a BitVec> for PostgresValue<'a> {
617    fn from(value: &'a BitVec) -> Self {
618        PostgresValue::BitVec(value.clone())
619    }
620}
621
622// --- Array Types ---
623
624impl<'a> From<Vec<PostgresValue<'a>>> for PostgresValue<'a> {
625    fn from(value: Vec<PostgresValue<'a>>) -> Self {
626        PostgresValue::Array(value)
627    }
628}
629
630impl<'a> From<&'a [PostgresValue<'a>]> for PostgresValue<'a> {
631    fn from(value: &'a [PostgresValue<'a>]) -> Self {
632        PostgresValue::Array(value.to_vec())
633    }
634}
635
636impl<'a> From<Vec<String>> for PostgresValue<'a> {
637    fn from(value: Vec<String>) -> Self {
638        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
639    }
640}
641
642impl<'a> From<Vec<&'a str>> for PostgresValue<'a> {
643    fn from(value: Vec<&'a str>) -> Self {
644        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
645    }
646}
647
648impl<'a> From<Vec<i16>> for PostgresValue<'a> {
649    fn from(value: Vec<i16>) -> Self {
650        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
651    }
652}
653
654impl<'a> From<Vec<i32>> for PostgresValue<'a> {
655    fn from(value: Vec<i32>) -> Self {
656        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
657    }
658}
659
660impl<'a> From<Vec<i64>> for PostgresValue<'a> {
661    fn from(value: Vec<i64>) -> Self {
662        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
663    }
664}
665
666impl<'a> From<Vec<f32>> for PostgresValue<'a> {
667    fn from(value: Vec<f32>) -> Self {
668        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
669    }
670}
671
672impl<'a> From<Vec<f64>> for PostgresValue<'a> {
673    fn from(value: Vec<f64>) -> Self {
674        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
675    }
676}
677
678impl<'a> From<Vec<bool>> for PostgresValue<'a> {
679    fn from(value: Vec<bool>) -> Self {
680        PostgresValue::Array(value.into_iter().map(PostgresValue::from).collect())
681    }
682}
683
684// --- Option Types ---
685impl<'a, T> From<Option<T>> for PostgresValue<'a>
686where
687    T: TryInto<PostgresValue<'a>>,
688{
689    fn from(value: Option<T>) -> Self {
690        match value {
691            Some(value) => value.try_into().unwrap_or(PostgresValue::Null),
692            None => PostgresValue::Null,
693        }
694    }
695}
696
697//------------------------------------------------------------------------------
698// TryFrom<PostgresValue> implementations
699//------------------------------------------------------------------------------
700
701// --- Integer Types ---
702
703impl<'a> TryFrom<PostgresValue<'a>> for i16 {
704    type Error = DrizzleError;
705
706    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
707        match value {
708            PostgresValue::Smallint(i) => Ok(i),
709            PostgresValue::Integer(i) => Ok(i.try_into()?),
710            PostgresValue::Bigint(i) => Ok(i.try_into()?),
711            _ => Err(DrizzleError::ConversionError(
712                format!("Cannot convert {:?} to i16", value).into(),
713            )),
714        }
715    }
716}
717
718impl<'a> TryFrom<PostgresValue<'a>> for i32 {
719    type Error = DrizzleError;
720
721    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
722        match value {
723            PostgresValue::Smallint(i) => Ok(i.into()),
724            PostgresValue::Integer(i) => Ok(i),
725            PostgresValue::Bigint(i) => Ok(i.try_into()?),
726            _ => Err(DrizzleError::ConversionError(
727                format!("Cannot convert {:?} to i32", value).into(),
728            )),
729        }
730    }
731}
732
733impl<'a> TryFrom<PostgresValue<'a>> for i64 {
734    type Error = DrizzleError;
735
736    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
737        match value {
738            PostgresValue::Smallint(i) => Ok(i.into()),
739            PostgresValue::Integer(i) => Ok(i.into()),
740            PostgresValue::Bigint(i) => Ok(i),
741            _ => Err(DrizzleError::ConversionError(
742                format!("Cannot convert {:?} to i64", value).into(),
743            )),
744        }
745    }
746}
747
748// --- Floating Point Types ---
749
750impl<'a> TryFrom<PostgresValue<'a>> for f32 {
751    type Error = DrizzleError;
752
753    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
754        match value {
755            PostgresValue::Real(f) => Ok(f),
756            PostgresValue::DoublePrecision(f) => Ok(f as f32),
757            PostgresValue::Smallint(i) => Ok(i as f32),
758            PostgresValue::Integer(i) => Ok(i as f32),
759            PostgresValue::Bigint(i) => Ok(i as f32),
760            _ => Err(DrizzleError::ConversionError(
761                format!("Cannot convert {:?} to f32", value).into(),
762            )),
763        }
764    }
765}
766
767impl<'a> TryFrom<PostgresValue<'a>> for f64 {
768    type Error = DrizzleError;
769
770    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
771        match value {
772            PostgresValue::Real(f) => Ok(f as f64),
773            PostgresValue::DoublePrecision(f) => Ok(f),
774            PostgresValue::Smallint(i) => Ok(i as f64),
775            PostgresValue::Integer(i) => Ok(i as f64),
776            PostgresValue::Bigint(i) => Ok(i as f64),
777            _ => Err(DrizzleError::ConversionError(
778                format!("Cannot convert {:?} to f64", value).into(),
779            )),
780        }
781    }
782}
783
784// --- Boolean ---
785
786impl<'a> TryFrom<PostgresValue<'a>> for bool {
787    type Error = DrizzleError;
788
789    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
790        match value {
791            PostgresValue::Boolean(b) => Ok(b),
792            _ => Err(DrizzleError::ConversionError(
793                format!("Cannot convert {:?} to bool", value).into(),
794            )),
795        }
796    }
797}
798
799// --- String Types ---
800
801impl<'a> TryFrom<PostgresValue<'a>> for String {
802    type Error = DrizzleError;
803
804    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
805        match value {
806            PostgresValue::Text(cow) => Ok(cow.into_owned()),
807            _ => Err(DrizzleError::ConversionError(
808                format!("Cannot convert {:?} to String", value).into(),
809            )),
810        }
811    }
812}
813
814impl<'a> TryFrom<PostgresValue<'a>> for Box<String> {
815    type Error = DrizzleError;
816
817    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
818        String::try_from(value).map(Box::new)
819    }
820}
821
822impl<'a> TryFrom<PostgresValue<'a>> for Rc<String> {
823    type Error = DrizzleError;
824
825    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
826        String::try_from(value).map(Rc::new)
827    }
828}
829
830impl<'a> TryFrom<PostgresValue<'a>> for Arc<String> {
831    type Error = DrizzleError;
832
833    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
834        String::try_from(value).map(Arc::new)
835    }
836}
837
838impl<'a> TryFrom<PostgresValue<'a>> for Box<str> {
839    type Error = DrizzleError;
840
841    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
842        match value {
843            PostgresValue::Text(cow) => Ok(cow.into_owned().into_boxed_str()),
844            _ => Err(DrizzleError::ConversionError(
845                format!("Cannot convert {:?} to Box<str>", value).into(),
846            )),
847        }
848    }
849}
850
851impl<'a> TryFrom<PostgresValue<'a>> for Rc<str> {
852    type Error = DrizzleError;
853
854    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
855        match value {
856            PostgresValue::Text(cow) => Ok(Rc::from(cow.into_owned())),
857            _ => Err(DrizzleError::ConversionError(
858                format!("Cannot convert {:?} to Rc<str>", value).into(),
859            )),
860        }
861    }
862}
863
864impl<'a> TryFrom<PostgresValue<'a>> for Arc<str> {
865    type Error = DrizzleError;
866
867    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
868        match value {
869            PostgresValue::Text(cow) => Ok(Arc::from(cow.into_owned())),
870            _ => Err(DrizzleError::ConversionError(
871                format!("Cannot convert {:?} to Arc<str>", value).into(),
872            )),
873        }
874    }
875}
876
877// --- Binary Data ---
878
879impl<'a> TryFrom<PostgresValue<'a>> for Vec<u8> {
880    type Error = DrizzleError;
881
882    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
883        match value {
884            PostgresValue::Bytea(cow) => Ok(cow.into_owned()),
885            _ => Err(DrizzleError::ConversionError(
886                format!("Cannot convert {:?} to Vec<u8>", value).into(),
887            )),
888        }
889    }
890}
891
892impl<'a> TryFrom<PostgresValue<'a>> for Box<Vec<u8>> {
893    type Error = DrizzleError;
894
895    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
896        Vec::<u8>::try_from(value).map(Box::new)
897    }
898}
899
900impl<'a> TryFrom<PostgresValue<'a>> for Rc<Vec<u8>> {
901    type Error = DrizzleError;
902
903    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
904        Vec::<u8>::try_from(value).map(Rc::new)
905    }
906}
907
908impl<'a> TryFrom<PostgresValue<'a>> for Arc<Vec<u8>> {
909    type Error = DrizzleError;
910
911    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
912        Vec::<u8>::try_from(value).map(Arc::new)
913    }
914}
915
916impl<'a> TryFrom<&'a PostgresValue<'a>> for &'a str {
917    type Error = DrizzleError;
918
919    fn try_from(value: &'a PostgresValue<'a>) -> Result<Self, Self::Error> {
920        match value {
921            PostgresValue::Text(cow) => Ok(cow.as_ref()),
922            _ => Err(DrizzleError::ConversionError(
923                format!("Cannot convert {:?} to &str", value).into(),
924            )),
925        }
926    }
927}
928
929impl<'a> TryFrom<&'a PostgresValue<'a>> for &'a [u8] {
930    type Error = DrizzleError;
931
932    fn try_from(value: &'a PostgresValue<'a>) -> Result<Self, Self::Error> {
933        match value {
934            PostgresValue::Bytea(cow) => Ok(cow.as_ref()),
935            _ => Err(DrizzleError::ConversionError(
936                format!("Cannot convert {:?} to &[u8]", value).into(),
937            )),
938        }
939    }
940}
941
942// --- UUID ---
943
944#[cfg(feature = "uuid")]
945impl<'a> TryFrom<PostgresValue<'a>> for Uuid {
946    type Error = DrizzleError;
947
948    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
949        match value {
950            PostgresValue::Uuid(uuid) => Ok(uuid),
951            PostgresValue::Text(cow) => Uuid::parse_str(cow.as_ref()).map_err(|e| {
952                DrizzleError::ConversionError(format!("Failed to parse UUID: {}", e).into())
953            }),
954            _ => Err(DrizzleError::ConversionError(
955                format!("Cannot convert {:?} to UUID", value).into(),
956            )),
957        }
958    }
959}
960
961// --- JSON ---
962
963#[cfg(feature = "serde")]
964impl<'a> TryFrom<PostgresValue<'a>> for serde_json::Value {
965    type Error = DrizzleError;
966
967    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
968        match value {
969            PostgresValue::Json(json) => Ok(json),
970            PostgresValue::Jsonb(json) => Ok(json),
971            PostgresValue::Text(cow) => serde_json::from_str(cow.as_ref()).map_err(|e| {
972                DrizzleError::ConversionError(format!("Failed to parse JSON: {}", e).into())
973            }),
974            _ => Err(DrizzleError::ConversionError(
975                format!("Cannot convert {:?} to JSON", value).into(),
976            )),
977        }
978    }
979}
980
981// --- Date/Time TryFrom implementations ---
982
983#[cfg(feature = "chrono")]
984impl<'a> TryFrom<PostgresValue<'a>> for NaiveDate {
985    type Error = DrizzleError;
986
987    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
988        match value {
989            PostgresValue::Date(date) => Ok(date),
990            PostgresValue::Timestamp(ts) => Ok(ts.date()),
991            PostgresValue::TimestampTz(ts) => Ok(ts.date_naive()),
992            _ => Err(DrizzleError::ConversionError(
993                format!("Cannot convert {:?} to NaiveDate", value).into(),
994            )),
995        }
996    }
997}
998
999#[cfg(feature = "chrono")]
1000impl<'a> TryFrom<PostgresValue<'a>> for NaiveTime {
1001    type Error = DrizzleError;
1002
1003    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1004        match value {
1005            PostgresValue::Time(time) => Ok(time),
1006            PostgresValue::Timestamp(ts) => Ok(ts.time()),
1007            PostgresValue::TimestampTz(ts) => Ok(ts.time()),
1008            _ => Err(DrizzleError::ConversionError(
1009                format!("Cannot convert {:?} to NaiveTime", value).into(),
1010            )),
1011        }
1012    }
1013}
1014
1015#[cfg(feature = "chrono")]
1016impl<'a> TryFrom<PostgresValue<'a>> for NaiveDateTime {
1017    type Error = DrizzleError;
1018
1019    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1020        match value {
1021            PostgresValue::Timestamp(ts) => Ok(ts),
1022            PostgresValue::TimestampTz(ts) => Ok(ts.naive_utc()),
1023            _ => Err(DrizzleError::ConversionError(
1024                format!("Cannot convert {:?} to NaiveDateTime", value).into(),
1025            )),
1026        }
1027    }
1028}
1029
1030#[cfg(feature = "chrono")]
1031impl<'a> TryFrom<PostgresValue<'a>> for DateTime<FixedOffset> {
1032    type Error = DrizzleError;
1033
1034    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1035        match value {
1036            PostgresValue::TimestampTz(ts) => Ok(ts),
1037            _ => Err(DrizzleError::ConversionError(
1038                format!("Cannot convert {:?} to DateTime<FixedOffset>", value).into(),
1039            )),
1040        }
1041    }
1042}
1043
1044#[cfg(feature = "chrono")]
1045impl<'a> TryFrom<PostgresValue<'a>> for DateTime<Utc> {
1046    type Error = DrizzleError;
1047
1048    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1049        match value {
1050            PostgresValue::TimestampTz(ts) => Ok(ts.with_timezone(&Utc)),
1051            _ => Err(DrizzleError::ConversionError(
1052                format!("Cannot convert {:?} to DateTime<Utc>", value).into(),
1053            )),
1054        }
1055    }
1056}
1057
1058#[cfg(feature = "chrono")]
1059impl<'a> TryFrom<PostgresValue<'a>> for Duration {
1060    type Error = DrizzleError;
1061
1062    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1063        match value {
1064            PostgresValue::Interval(duration) => Ok(duration),
1065            _ => Err(DrizzleError::ConversionError(
1066                format!("Cannot convert {:?} to Duration", value).into(),
1067            )),
1068        }
1069    }
1070}
1071
1072// --- Network Address TryFrom implementations ---
1073
1074#[cfg(feature = "cidr")]
1075impl<'a> TryFrom<PostgresValue<'a>> for IpInet {
1076    type Error = DrizzleError;
1077
1078    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1079        match value {
1080            PostgresValue::Inet(net) => Ok(net),
1081            _ => Err(DrizzleError::ConversionError(
1082                format!("Cannot convert {:?} to IpInet", value).into(),
1083            )),
1084        }
1085    }
1086}
1087
1088#[cfg(feature = "cidr")]
1089impl<'a> TryFrom<PostgresValue<'a>> for IpCidr {
1090    type Error = DrizzleError;
1091
1092    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1093        match value {
1094            PostgresValue::Cidr(net) => Ok(net),
1095            _ => Err(DrizzleError::ConversionError(
1096                format!("Cannot convert {:?} to IpCidr", value).into(),
1097            )),
1098        }
1099    }
1100}
1101
1102#[cfg(feature = "cidr")]
1103impl<'a> TryFrom<PostgresValue<'a>> for [u8; 6] {
1104    type Error = DrizzleError;
1105
1106    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1107        match value {
1108            PostgresValue::MacAddr(mac) => Ok(mac),
1109            _ => Err(DrizzleError::ConversionError(
1110                format!("Cannot convert {:?} to [u8; 6]", value).into(),
1111            )),
1112        }
1113    }
1114}
1115
1116#[cfg(feature = "cidr")]
1117impl<'a> TryFrom<PostgresValue<'a>> for [u8; 8] {
1118    type Error = DrizzleError;
1119
1120    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1121        match value {
1122            PostgresValue::MacAddr8(mac) => Ok(mac),
1123            _ => Err(DrizzleError::ConversionError(
1124                format!("Cannot convert {:?} to [u8; 8]", value).into(),
1125            )),
1126        }
1127    }
1128}
1129
1130// --- Geometric TryFrom implementations ---
1131
1132#[cfg(feature = "geo-types")]
1133impl<'a> TryFrom<PostgresValue<'a>> for Point<f64> {
1134    type Error = DrizzleError;
1135
1136    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1137        match value {
1138            PostgresValue::Point(point) => Ok(point),
1139            _ => Err(DrizzleError::ConversionError(
1140                format!("Cannot convert {:?} to Point", value).into(),
1141            )),
1142        }
1143    }
1144}
1145
1146#[cfg(feature = "geo-types")]
1147impl<'a> TryFrom<PostgresValue<'a>> for LineString<f64> {
1148    type Error = DrizzleError;
1149
1150    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1151        match value {
1152            PostgresValue::LineString(line) => Ok(line),
1153            _ => Err(DrizzleError::ConversionError(
1154                format!("Cannot convert {:?} to LineString", value).into(),
1155            )),
1156        }
1157    }
1158}
1159
1160#[cfg(feature = "geo-types")]
1161impl<'a> TryFrom<PostgresValue<'a>> for Rect<f64> {
1162    type Error = DrizzleError;
1163
1164    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1165        match value {
1166            PostgresValue::Rect(rect) => Ok(rect),
1167            _ => Err(DrizzleError::ConversionError(
1168                format!("Cannot convert {:?} to Rect", value).into(),
1169            )),
1170        }
1171    }
1172}
1173
1174// --- Bit String TryFrom implementations ---
1175
1176#[cfg(feature = "bit-vec")]
1177impl<'a> TryFrom<PostgresValue<'a>> for BitVec {
1178    type Error = DrizzleError;
1179
1180    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1181        match value {
1182            PostgresValue::BitVec(bv) => Ok(bv),
1183            _ => Err(DrizzleError::ConversionError(
1184                format!("Cannot convert {:?} to BitVec", value).into(),
1185            )),
1186        }
1187    }
1188}
1189
1190// --- ArrayVec TryFrom implementations ---
1191
1192#[cfg(feature = "arrayvec")]
1193impl<'a, const N: usize> TryFrom<PostgresValue<'a>> for arrayvec::ArrayString<N> {
1194    type Error = DrizzleError;
1195
1196    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1197        match value {
1198            PostgresValue::Text(cow_str) => {
1199                arrayvec::ArrayString::from(cow_str.as_ref()).map_err(|_| {
1200                    DrizzleError::ConversionError(
1201                        format!(
1202                            "Text length {} exceeds ArrayString capacity {}",
1203                            cow_str.len(),
1204                            N
1205                        )
1206                        .into(),
1207                    )
1208                })
1209            }
1210            _ => Err(DrizzleError::ConversionError(
1211                format!("Cannot convert {:?} to ArrayString", value).into(),
1212            )),
1213        }
1214    }
1215}
1216
1217#[cfg(feature = "arrayvec")]
1218impl<'a, const N: usize> TryFrom<PostgresValue<'a>> for arrayvec::ArrayVec<u8, N> {
1219    type Error = DrizzleError;
1220
1221    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1222        match value {
1223            PostgresValue::Bytea(cow_bytes) => arrayvec::ArrayVec::try_from(cow_bytes.as_ref())
1224                .map_err(|_| {
1225                    DrizzleError::ConversionError(
1226                        format!(
1227                            "Bytea length {} exceeds ArrayVec capacity {}",
1228                            cow_bytes.len(),
1229                            N
1230                        )
1231                        .into(),
1232                    )
1233                }),
1234            _ => Err(DrizzleError::ConversionError(
1235                format!("Cannot convert {:?} to ArrayVec<u8>", value).into(),
1236            )),
1237        }
1238    }
1239}
1240
1241// --- Array TryFrom implementations ---
1242
1243impl<'a> TryFrom<PostgresValue<'a>> for Vec<PostgresValue<'a>> {
1244    type Error = DrizzleError;
1245
1246    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1247        match value {
1248            PostgresValue::Array(arr) => Ok(arr),
1249            _ => Err(DrizzleError::ConversionError(
1250                format!("Cannot convert {:?} to Vec<PostgresValue>", value).into(),
1251            )),
1252        }
1253    }
1254}
1255
1256impl<'a> TryFrom<&'a PostgresValue<'a>> for &'a [PostgresValue<'a>] {
1257    type Error = DrizzleError;
1258
1259    fn try_from(value: &'a PostgresValue<'a>) -> Result<Self, Self::Error> {
1260        match value {
1261            PostgresValue::Array(arr) => Ok(arr),
1262            _ => Err(DrizzleError::ConversionError(
1263                format!("Cannot convert {:?} to &[PostgresValue]", value).into(),
1264            )),
1265        }
1266    }
1267}