drizzle_postgres/traits/
value.rs

1//! Value conversion traits for PostgreSQL types
2//!
3//! This module provides the `FromPostgresValue` trait for converting PostgreSQL values
4//! to Rust types, and the `DrizzleRow` trait for unified row access across drivers.
5//!
6//! This pattern mirrors the SQLite implementation to provide driver-agnostic
7//! row conversions for postgres, tokio-postgres, and potentially other drivers.
8
9use crate::values::{OwnedPostgresValue, PostgresValue};
10use drizzle_core::error::DrizzleError;
11
12/// Trait for types that can be converted from PostgreSQL values.
13///
14/// PostgreSQL has many types, but this trait focuses on the core conversions:
15/// - Integers (i16, i32, i64)
16/// - Floats (f32, f64)
17/// - Text (String, &str)
18/// - Binary (Vec<u8>, &[u8])
19/// - Boolean
20/// - NULL handling
21///
22/// # Implementation Notes
23///
24/// - Implement the methods that make sense for your type
25/// - Return `Err` for unsupported conversions
26/// - `PostgresEnum` derive automatically implements this trait
27pub trait FromPostgresValue: Sized {
28    /// Convert from a boolean value
29    fn from_postgres_bool(value: bool) -> Result<Self, DrizzleError>;
30
31    /// Convert from a 16-bit integer value
32    fn from_postgres_i16(value: i16) -> Result<Self, DrizzleError>;
33
34    /// Convert from a 32-bit integer value
35    fn from_postgres_i32(value: i32) -> Result<Self, DrizzleError>;
36
37    /// Convert from a 64-bit integer value
38    fn from_postgres_i64(value: i64) -> Result<Self, DrizzleError>;
39
40    /// Convert from a 32-bit float value
41    fn from_postgres_f32(value: f32) -> Result<Self, DrizzleError>;
42
43    /// Convert from a 64-bit float value
44    fn from_postgres_f64(value: f64) -> Result<Self, DrizzleError>;
45
46    /// Convert from a text/string value
47    fn from_postgres_text(value: &str) -> Result<Self, DrizzleError>;
48
49    /// Convert from a binary/bytea value
50    fn from_postgres_bytes(value: &[u8]) -> Result<Self, DrizzleError>;
51
52    /// Convert from a NULL value (default returns error)
53    fn from_postgres_null() -> Result<Self, DrizzleError> {
54        Err(DrizzleError::ConversionError(
55            "unexpected NULL value".into(),
56        ))
57    }
58
59    /// Convert from a UUID value
60    #[cfg(feature = "uuid")]
61    fn from_postgres_uuid(value: uuid::Uuid) -> Result<Self, DrizzleError> {
62        Err(DrizzleError::ConversionError(
63            format!("cannot convert UUID {} to target type", value).into(),
64        ))
65    }
66
67    /// Convert from a JSON value
68    #[cfg(feature = "serde")]
69    fn from_postgres_json(value: serde_json::Value) -> Result<Self, DrizzleError> {
70        Err(DrizzleError::ConversionError(
71            format!("cannot convert JSON {} to target type", value).into(),
72        ))
73    }
74
75    /// Convert from a JSONB value
76    #[cfg(feature = "serde")]
77    fn from_postgres_jsonb(value: serde_json::Value) -> Result<Self, DrizzleError> {
78        Err(DrizzleError::ConversionError(
79            format!("cannot convert JSONB {} to target type", value).into(),
80        ))
81    }
82
83    /// Convert from an ARRAY value
84    fn from_postgres_array<'a>(_value: Vec<PostgresValue<'a>>) -> Result<Self, DrizzleError> {
85        Err(DrizzleError::ConversionError(
86            "cannot convert ARRAY to target type".into(),
87        ))
88    }
89
90    /// Convert from a DATE value
91    #[cfg(feature = "chrono")]
92    fn from_postgres_date(value: chrono::NaiveDate) -> Result<Self, DrizzleError> {
93        Err(DrizzleError::ConversionError(
94            format!("cannot convert DATE {} to target type", value).into(),
95        ))
96    }
97
98    /// Convert from a TIME value
99    #[cfg(feature = "chrono")]
100    fn from_postgres_time(value: chrono::NaiveTime) -> Result<Self, DrizzleError> {
101        Err(DrizzleError::ConversionError(
102            format!("cannot convert TIME {} to target type", value).into(),
103        ))
104    }
105
106    /// Convert from a TIMESTAMP value
107    #[cfg(feature = "chrono")]
108    fn from_postgres_timestamp(value: chrono::NaiveDateTime) -> Result<Self, DrizzleError> {
109        Err(DrizzleError::ConversionError(
110            format!("cannot convert TIMESTAMP {} to target type", value).into(),
111        ))
112    }
113
114    /// Convert from a TIMESTAMPTZ value
115    #[cfg(feature = "chrono")]
116    fn from_postgres_timestamptz(
117        value: chrono::DateTime<chrono::FixedOffset>,
118    ) -> Result<Self, DrizzleError> {
119        Err(DrizzleError::ConversionError(
120            format!("cannot convert TIMESTAMPTZ {} to target type", value).into(),
121        ))
122    }
123
124    /// Convert from an INTERVAL value
125    #[cfg(feature = "chrono")]
126    fn from_postgres_interval(value: chrono::Duration) -> Result<Self, DrizzleError> {
127        Err(DrizzleError::ConversionError(
128            format!("cannot convert INTERVAL {} to target type", value).into(),
129        ))
130    }
131
132    /// Convert from an INET value
133    #[cfg(feature = "cidr")]
134    fn from_postgres_inet(value: cidr::IpInet) -> Result<Self, DrizzleError> {
135        Err(DrizzleError::ConversionError(
136            format!("cannot convert INET {} to target type", value).into(),
137        ))
138    }
139
140    /// Convert from a CIDR value
141    #[cfg(feature = "cidr")]
142    fn from_postgres_cidr(value: cidr::IpCidr) -> Result<Self, DrizzleError> {
143        Err(DrizzleError::ConversionError(
144            format!("cannot convert CIDR {} to target type", value).into(),
145        ))
146    }
147
148    /// Convert from a MACADDR value
149    #[cfg(feature = "cidr")]
150    fn from_postgres_macaddr(value: [u8; 6]) -> Result<Self, DrizzleError> {
151        Err(DrizzleError::ConversionError(
152            format!("cannot convert MACADDR {:?} to target type", value).into(),
153        ))
154    }
155
156    /// Convert from a MACADDR8 value
157    #[cfg(feature = "cidr")]
158    fn from_postgres_macaddr8(value: [u8; 8]) -> Result<Self, DrizzleError> {
159        Err(DrizzleError::ConversionError(
160            format!("cannot convert MACADDR8 {:?} to target type", value).into(),
161        ))
162    }
163
164    /// Convert from a POINT value
165    #[cfg(feature = "geo-types")]
166    fn from_postgres_point(value: geo_types::Point<f64>) -> Result<Self, DrizzleError> {
167        Err(DrizzleError::ConversionError(
168            format!("cannot convert POINT {:?} to target type", value).into(),
169        ))
170    }
171
172    /// Convert from a PATH value
173    #[cfg(feature = "geo-types")]
174    fn from_postgres_linestring(value: geo_types::LineString<f64>) -> Result<Self, DrizzleError> {
175        Err(DrizzleError::ConversionError(
176            format!("cannot convert PATH {:?} to target type", value).into(),
177        ))
178    }
179
180    /// Convert from a BOX value
181    #[cfg(feature = "geo-types")]
182    fn from_postgres_rect(value: geo_types::Rect<f64>) -> Result<Self, DrizzleError> {
183        Err(DrizzleError::ConversionError(
184            format!("cannot convert BOX {:?} to target type", value).into(),
185        ))
186    }
187
188    /// Convert from a BIT/VARBIT value
189    #[cfg(feature = "bit-vec")]
190    fn from_postgres_bitvec(value: bit_vec::BitVec) -> Result<Self, DrizzleError> {
191        Err(DrizzleError::ConversionError(
192            format!("cannot convert BITVEC {:?} to target type", value).into(),
193        ))
194    }
195}
196
197/// Trait for database rows that can extract values using `FromPostgresValue`.
198///
199/// This provides a unified interface for extracting values from database rows
200/// across different PostgreSQL drivers (postgres, tokio-postgres).
201pub trait DrizzleRow {
202    /// Get a column value by index
203    fn get_column<T: FromPostgresValue>(&self, idx: usize) -> Result<T, DrizzleError>;
204
205    /// Get a column value by name
206    fn get_column_by_name<T: FromPostgresValue>(&self, name: &str) -> Result<T, DrizzleError>;
207}
208
209// =============================================================================
210// Primitive implementations
211// =============================================================================
212
213impl FromPostgresValue for bool {
214    fn from_postgres_bool(value: bool) -> Result<Self, DrizzleError> {
215        Ok(value)
216    }
217
218    fn from_postgres_i16(value: i16) -> Result<Self, DrizzleError> {
219        Ok(value != 0)
220    }
221
222    fn from_postgres_i32(value: i32) -> Result<Self, DrizzleError> {
223        Ok(value != 0)
224    }
225
226    fn from_postgres_i64(value: i64) -> Result<Self, DrizzleError> {
227        Ok(value != 0)
228    }
229
230    fn from_postgres_f32(_value: f32) -> Result<Self, DrizzleError> {
231        Err(DrizzleError::ConversionError(
232            "cannot convert f32 to bool".into(),
233        ))
234    }
235
236    fn from_postgres_f64(_value: f64) -> Result<Self, DrizzleError> {
237        Err(DrizzleError::ConversionError(
238            "cannot convert f64 to bool".into(),
239        ))
240    }
241
242    fn from_postgres_text(value: &str) -> Result<Self, DrizzleError> {
243        match value.to_lowercase().as_str() {
244            "true" | "t" | "1" | "yes" | "on" => Ok(true),
245            "false" | "f" | "0" | "no" | "off" => Ok(false),
246            _ => Err(DrizzleError::ConversionError(
247                format!("cannot parse '{}' as bool", value).into(),
248            )),
249        }
250    }
251
252    fn from_postgres_bytes(_value: &[u8]) -> Result<Self, DrizzleError> {
253        Err(DrizzleError::ConversionError(
254            "cannot convert bytes to bool".into(),
255        ))
256    }
257}
258
259/// Macro to implement FromPostgresValue for integer types
260macro_rules! impl_from_postgres_value_int {
261    ($($ty:ty),+ $(,)?) => {
262        $(
263            impl FromPostgresValue for $ty {
264                fn from_postgres_bool(value: bool) -> Result<Self, DrizzleError> {
265                    Ok(if value { 1 } else { 0 })
266                }
267
268                fn from_postgres_i16(value: i16) -> Result<Self, DrizzleError> {
269                    value.try_into().map_err(|e| {
270                        DrizzleError::ConversionError(
271                            format!("i16 {} out of range for {}: {}", value, stringify!($ty), e).into(),
272                        )
273                    })
274                }
275
276                fn from_postgres_i32(value: i32) -> Result<Self, DrizzleError> {
277                    value.try_into().map_err(|e| {
278                        DrizzleError::ConversionError(
279                            format!("i32 {} out of range for {}: {}", value, stringify!($ty), e).into(),
280                        )
281                    })
282                }
283
284                fn from_postgres_i64(value: i64) -> Result<Self, DrizzleError> {
285                    value.try_into().map_err(|e| {
286                        DrizzleError::ConversionError(
287                            format!("i64 {} out of range for {}: {}", value, stringify!($ty), e).into(),
288                        )
289                    })
290                }
291
292                fn from_postgres_f32(value: f32) -> Result<Self, DrizzleError> {
293                    Ok(value as $ty)
294                }
295
296                fn from_postgres_f64(value: f64) -> Result<Self, DrizzleError> {
297                    Ok(value as $ty)
298                }
299
300                fn from_postgres_text(value: &str) -> Result<Self, DrizzleError> {
301                    value.parse().map_err(|e| {
302                        DrizzleError::ConversionError(
303                            format!("cannot parse '{}' as {}: {}", value, stringify!($ty), e).into()
304                        )
305                    })
306                }
307
308                fn from_postgres_bytes(_value: &[u8]) -> Result<Self, DrizzleError> {
309                    Err(DrizzleError::ConversionError(
310                        concat!("cannot convert bytes to ", stringify!($ty)).into()
311                    ))
312                }
313            }
314        )+
315    };
316}
317
318// Special case for i16 - no conversion needed
319impl FromPostgresValue for i16 {
320    fn from_postgres_bool(value: bool) -> Result<Self, DrizzleError> {
321        Ok(if value { 1 } else { 0 })
322    }
323
324    fn from_postgres_i16(value: i16) -> Result<Self, DrizzleError> {
325        Ok(value)
326    }
327
328    fn from_postgres_i32(value: i32) -> Result<Self, DrizzleError> {
329        value.try_into().map_err(|e| {
330            DrizzleError::ConversionError(
331                format!("i32 {} out of range for i16: {}", value, e).into(),
332            )
333        })
334    }
335
336    fn from_postgres_i64(value: i64) -> Result<Self, DrizzleError> {
337        value.try_into().map_err(|e| {
338            DrizzleError::ConversionError(
339                format!("i64 {} out of range for i16: {}", value, e).into(),
340            )
341        })
342    }
343
344    fn from_postgres_f32(value: f32) -> Result<Self, DrizzleError> {
345        Ok(value as i16)
346    }
347
348    fn from_postgres_f64(value: f64) -> Result<Self, DrizzleError> {
349        Ok(value as i16)
350    }
351
352    fn from_postgres_text(value: &str) -> Result<Self, DrizzleError> {
353        value.parse().map_err(|e| {
354            DrizzleError::ConversionError(format!("cannot parse '{}' as i16: {}", value, e).into())
355        })
356    }
357
358    fn from_postgres_bytes(_value: &[u8]) -> Result<Self, DrizzleError> {
359        Err(DrizzleError::ConversionError(
360            "cannot convert bytes to i16".into(),
361        ))
362    }
363}
364
365// Special case for i32 - no conversion needed
366impl FromPostgresValue for i32 {
367    fn from_postgres_bool(value: bool) -> Result<Self, DrizzleError> {
368        Ok(if value { 1 } else { 0 })
369    }
370
371    fn from_postgres_i16(value: i16) -> Result<Self, DrizzleError> {
372        Ok(value as i32)
373    }
374
375    fn from_postgres_i32(value: i32) -> Result<Self, DrizzleError> {
376        Ok(value)
377    }
378
379    fn from_postgres_i64(value: i64) -> Result<Self, DrizzleError> {
380        value.try_into().map_err(|e| {
381            DrizzleError::ConversionError(
382                format!("i64 {} out of range for i32: {}", value, e).into(),
383            )
384        })
385    }
386
387    fn from_postgres_f32(value: f32) -> Result<Self, DrizzleError> {
388        Ok(value as i32)
389    }
390
391    fn from_postgres_f64(value: f64) -> Result<Self, DrizzleError> {
392        Ok(value as i32)
393    }
394
395    fn from_postgres_text(value: &str) -> Result<Self, DrizzleError> {
396        value.parse().map_err(|e| {
397            DrizzleError::ConversionError(format!("cannot parse '{}' as i32: {}", value, e).into())
398        })
399    }
400
401    fn from_postgres_bytes(_value: &[u8]) -> Result<Self, DrizzleError> {
402        Err(DrizzleError::ConversionError(
403            "cannot convert bytes to i32".into(),
404        ))
405    }
406}
407
408// Special case for i64 - no conversion needed
409impl FromPostgresValue for i64 {
410    fn from_postgres_bool(value: bool) -> Result<Self, DrizzleError> {
411        Ok(if value { 1 } else { 0 })
412    }
413
414    fn from_postgres_i16(value: i16) -> Result<Self, DrizzleError> {
415        Ok(value as i64)
416    }
417
418    fn from_postgres_i32(value: i32) -> Result<Self, DrizzleError> {
419        Ok(value as i64)
420    }
421
422    fn from_postgres_i64(value: i64) -> Result<Self, DrizzleError> {
423        Ok(value)
424    }
425
426    fn from_postgres_f32(value: f32) -> Result<Self, DrizzleError> {
427        Ok(value as i64)
428    }
429
430    fn from_postgres_f64(value: f64) -> Result<Self, DrizzleError> {
431        Ok(value as i64)
432    }
433
434    fn from_postgres_text(value: &str) -> Result<Self, DrizzleError> {
435        value.parse().map_err(|e| {
436            DrizzleError::ConversionError(format!("cannot parse '{}' as i64: {}", value, e).into())
437        })
438    }
439
440    fn from_postgres_bytes(_value: &[u8]) -> Result<Self, DrizzleError> {
441        Err(DrizzleError::ConversionError(
442            "cannot convert bytes to i64".into(),
443        ))
444    }
445}
446
447// Other integer types that need conversion
448impl_from_postgres_value_int!(i8, u8, u16, u32, u64, isize, usize);
449
450/// Macro to implement FromPostgresValue for float types
451macro_rules! impl_from_postgres_value_float {
452    ($($ty:ty),+ $(,)?) => {
453        $(
454            impl FromPostgresValue for $ty {
455                fn from_postgres_bool(value: bool) -> Result<Self, DrizzleError> {
456                    Ok(if value { 1.0 } else { 0.0 })
457                }
458
459                fn from_postgres_i16(value: i16) -> Result<Self, DrizzleError> {
460                    Ok(value as $ty)
461                }
462
463                fn from_postgres_i32(value: i32) -> Result<Self, DrizzleError> {
464                    Ok(value as $ty)
465                }
466
467                fn from_postgres_i64(value: i64) -> Result<Self, DrizzleError> {
468                    Ok(value as $ty)
469                }
470
471                fn from_postgres_f32(value: f32) -> Result<Self, DrizzleError> {
472                    Ok(value as $ty)
473                }
474
475                fn from_postgres_f64(value: f64) -> Result<Self, DrizzleError> {
476                    Ok(value as $ty)
477                }
478
479                fn from_postgres_text(value: &str) -> Result<Self, DrizzleError> {
480                    value.parse().map_err(|e| {
481                        DrizzleError::ConversionError(
482                            format!("cannot parse '{}' as {}: {}", value, stringify!($ty), e).into()
483                        )
484                    })
485                }
486
487                fn from_postgres_bytes(_value: &[u8]) -> Result<Self, DrizzleError> {
488                    Err(DrizzleError::ConversionError(
489                        concat!("cannot convert bytes to ", stringify!($ty)).into()
490                    ))
491                }
492            }
493        )+
494    };
495}
496
497impl_from_postgres_value_float!(f32, f64);
498
499impl FromPostgresValue for String {
500    fn from_postgres_bool(value: bool) -> Result<Self, DrizzleError> {
501        Ok(value.to_string())
502    }
503
504    fn from_postgres_i16(value: i16) -> Result<Self, DrizzleError> {
505        Ok(value.to_string())
506    }
507
508    fn from_postgres_i32(value: i32) -> Result<Self, DrizzleError> {
509        Ok(value.to_string())
510    }
511
512    fn from_postgres_i64(value: i64) -> Result<Self, DrizzleError> {
513        Ok(value.to_string())
514    }
515
516    fn from_postgres_f32(value: f32) -> Result<Self, DrizzleError> {
517        Ok(value.to_string())
518    }
519
520    fn from_postgres_f64(value: f64) -> Result<Self, DrizzleError> {
521        Ok(value.to_string())
522    }
523
524    fn from_postgres_text(value: &str) -> Result<Self, DrizzleError> {
525        Ok(value.to_string())
526    }
527
528    fn from_postgres_bytes(value: &[u8]) -> Result<Self, DrizzleError> {
529        String::from_utf8(value.to_vec()).map_err(|e| {
530            DrizzleError::ConversionError(format!("invalid UTF-8 in bytes: {}", e).into())
531        })
532    }
533}
534
535impl FromPostgresValue for Vec<u8> {
536    fn from_postgres_bool(_value: bool) -> Result<Self, DrizzleError> {
537        Err(DrizzleError::ConversionError(
538            "cannot convert bool to Vec<u8>".into(),
539        ))
540    }
541
542    fn from_postgres_i16(value: i16) -> Result<Self, DrizzleError> {
543        Ok(value.to_le_bytes().to_vec())
544    }
545
546    fn from_postgres_i32(value: i32) -> Result<Self, DrizzleError> {
547        Ok(value.to_le_bytes().to_vec())
548    }
549
550    fn from_postgres_i64(value: i64) -> Result<Self, DrizzleError> {
551        Ok(value.to_le_bytes().to_vec())
552    }
553
554    fn from_postgres_f32(value: f32) -> Result<Self, DrizzleError> {
555        Ok(value.to_le_bytes().to_vec())
556    }
557
558    fn from_postgres_f64(value: f64) -> Result<Self, DrizzleError> {
559        Ok(value.to_le_bytes().to_vec())
560    }
561
562    fn from_postgres_text(value: &str) -> Result<Self, DrizzleError> {
563        Ok(value.as_bytes().to_vec())
564    }
565
566    fn from_postgres_bytes(value: &[u8]) -> Result<Self, DrizzleError> {
567        Ok(value.to_vec())
568    }
569}
570
571// Option<T> implementation - handles NULL values
572impl<T: FromPostgresValue> FromPostgresValue for Option<T> {
573    fn from_postgres_bool(value: bool) -> Result<Self, DrizzleError> {
574        T::from_postgres_bool(value).map(Some)
575    }
576
577    fn from_postgres_i16(value: i16) -> Result<Self, DrizzleError> {
578        T::from_postgres_i16(value).map(Some)
579    }
580
581    fn from_postgres_i32(value: i32) -> Result<Self, DrizzleError> {
582        T::from_postgres_i32(value).map(Some)
583    }
584
585    fn from_postgres_i64(value: i64) -> Result<Self, DrizzleError> {
586        T::from_postgres_i64(value).map(Some)
587    }
588
589    fn from_postgres_f32(value: f32) -> Result<Self, DrizzleError> {
590        T::from_postgres_f32(value).map(Some)
591    }
592
593    fn from_postgres_f64(value: f64) -> Result<Self, DrizzleError> {
594        T::from_postgres_f64(value).map(Some)
595    }
596
597    fn from_postgres_text(value: &str) -> Result<Self, DrizzleError> {
598        T::from_postgres_text(value).map(Some)
599    }
600
601    fn from_postgres_bytes(value: &[u8]) -> Result<Self, DrizzleError> {
602        T::from_postgres_bytes(value).map(Some)
603    }
604
605    #[cfg(feature = "uuid")]
606    fn from_postgres_uuid(value: uuid::Uuid) -> Result<Self, DrizzleError> {
607        T::from_postgres_uuid(value).map(Some)
608    }
609
610    #[cfg(feature = "serde")]
611    fn from_postgres_json(value: serde_json::Value) -> Result<Self, DrizzleError> {
612        T::from_postgres_json(value).map(Some)
613    }
614
615    #[cfg(feature = "serde")]
616    fn from_postgres_jsonb(value: serde_json::Value) -> Result<Self, DrizzleError> {
617        T::from_postgres_jsonb(value).map(Some)
618    }
619
620    #[cfg(feature = "chrono")]
621    fn from_postgres_date(value: chrono::NaiveDate) -> Result<Self, DrizzleError> {
622        T::from_postgres_date(value).map(Some)
623    }
624
625    #[cfg(feature = "chrono")]
626    fn from_postgres_time(value: chrono::NaiveTime) -> Result<Self, DrizzleError> {
627        T::from_postgres_time(value).map(Some)
628    }
629
630    #[cfg(feature = "chrono")]
631    fn from_postgres_timestamp(value: chrono::NaiveDateTime) -> Result<Self, DrizzleError> {
632        T::from_postgres_timestamp(value).map(Some)
633    }
634
635    #[cfg(feature = "chrono")]
636    fn from_postgres_timestamptz(
637        value: chrono::DateTime<chrono::FixedOffset>,
638    ) -> Result<Self, DrizzleError> {
639        T::from_postgres_timestamptz(value).map(Some)
640    }
641
642    #[cfg(feature = "chrono")]
643    fn from_postgres_interval(value: chrono::Duration) -> Result<Self, DrizzleError> {
644        T::from_postgres_interval(value).map(Some)
645    }
646
647    #[cfg(feature = "cidr")]
648    fn from_postgres_inet(value: cidr::IpInet) -> Result<Self, DrizzleError> {
649        T::from_postgres_inet(value).map(Some)
650    }
651
652    #[cfg(feature = "cidr")]
653    fn from_postgres_cidr(value: cidr::IpCidr) -> Result<Self, DrizzleError> {
654        T::from_postgres_cidr(value).map(Some)
655    }
656
657    #[cfg(feature = "cidr")]
658    fn from_postgres_macaddr(value: [u8; 6]) -> Result<Self, DrizzleError> {
659        T::from_postgres_macaddr(value).map(Some)
660    }
661
662    #[cfg(feature = "cidr")]
663    fn from_postgres_macaddr8(value: [u8; 8]) -> Result<Self, DrizzleError> {
664        T::from_postgres_macaddr8(value).map(Some)
665    }
666
667    #[cfg(feature = "geo-types")]
668    fn from_postgres_point(value: geo_types::Point<f64>) -> Result<Self, DrizzleError> {
669        T::from_postgres_point(value).map(Some)
670    }
671
672    #[cfg(feature = "geo-types")]
673    fn from_postgres_linestring(value: geo_types::LineString<f64>) -> Result<Self, DrizzleError> {
674        T::from_postgres_linestring(value).map(Some)
675    }
676
677    #[cfg(feature = "geo-types")]
678    fn from_postgres_rect(value: geo_types::Rect<f64>) -> Result<Self, DrizzleError> {
679        T::from_postgres_rect(value).map(Some)
680    }
681
682    #[cfg(feature = "bit-vec")]
683    fn from_postgres_bitvec(value: bit_vec::BitVec) -> Result<Self, DrizzleError> {
684        T::from_postgres_bitvec(value).map(Some)
685    }
686
687    fn from_postgres_array<'a>(value: Vec<PostgresValue<'a>>) -> Result<Self, DrizzleError> {
688        T::from_postgres_array(value).map(Some)
689    }
690
691    fn from_postgres_null() -> Result<Self, DrizzleError> {
692        Ok(None)
693    }
694}
695
696// =============================================================================
697// Driver-specific DrizzleRow implementations
698// =============================================================================
699
700// Note: postgres::Row is a re-export of tokio_postgres::Row, so we only need
701// to implement for one type. We use tokio_postgres::Row as it's the underlying type.
702// When only postgres-sync is enabled, postgres::Row will be available.
703
704#[cfg(any(feature = "postgres-sync", feature = "tokio-postgres"))]
705mod postgres_row_impl {
706    use super::*;
707
708    // Helper function to convert a row value to our type
709    // This uses the native driver's try_get functionality
710    fn convert_column<T: FromPostgresValue, R: PostgresRowLike>(
711        row: &R,
712        column: impl ColumnRef,
713    ) -> Result<T, DrizzleError> {
714        // Try bool first
715        if let Ok(Some(v)) = row.try_get_bool(&column) {
716            return T::from_postgres_bool(v);
717        }
718
719        // Try i64 (covers BIGINT)
720        if let Ok(Some(v)) = row.try_get_i64(&column) {
721            return T::from_postgres_i64(v);
722        }
723
724        // Try i32 (covers INTEGER)
725        if let Ok(Some(v)) = row.try_get_i32(&column) {
726            return T::from_postgres_i32(v);
727        }
728
729        // Try i16 (covers SMALLINT)
730        if let Ok(Some(v)) = row.try_get_i16(&column) {
731            return T::from_postgres_i16(v);
732        }
733
734        // Try f64 (covers DOUBLE PRECISION)
735        if let Ok(Some(v)) = row.try_get_f64(&column) {
736            return T::from_postgres_f64(v);
737        }
738
739        // Try f32 (covers REAL)
740        if let Ok(Some(v)) = row.try_get_f32(&column) {
741            return T::from_postgres_f32(v);
742        }
743
744        // Try String (covers TEXT, VARCHAR, etc.)
745        if let Ok(Some(ref v)) = row.try_get_string(&column) {
746            return T::from_postgres_text(v);
747        }
748
749        // Try bytes (covers BYTEA)
750        if let Ok(Some(ref v)) = row.try_get_bytes(&column) {
751            return T::from_postgres_bytes(v);
752        }
753
754        // Try UUID
755        #[cfg(feature = "uuid")]
756        if let Ok(Some(v)) = row.try_get_uuid(&column) {
757            return T::from_postgres_uuid(v);
758        }
759
760        // Try JSON/JSONB
761        #[cfg(feature = "serde")]
762        if let Ok(Some(v)) = row.try_get_json(&column) {
763            return T::from_postgres_json(v);
764        }
765
766        // Try chrono types
767        #[cfg(feature = "chrono")]
768        if let Ok(Some(v)) = row.try_get_date(&column) {
769            return T::from_postgres_date(v);
770        }
771
772        #[cfg(feature = "chrono")]
773        if let Ok(Some(v)) = row.try_get_time(&column) {
774            return T::from_postgres_time(v);
775        }
776
777        #[cfg(feature = "chrono")]
778        if let Ok(Some(v)) = row.try_get_timestamp(&column) {
779            return T::from_postgres_timestamp(v);
780        }
781
782        #[cfg(feature = "chrono")]
783        if let Ok(Some(v)) = row.try_get_timestamptz(&column) {
784            return T::from_postgres_timestamptz(v);
785        }
786
787        // Try network types
788        #[cfg(feature = "cidr")]
789        if let Ok(Some(v)) = row.try_get_inet(&column) {
790            return T::from_postgres_inet(v);
791        }
792
793        #[cfg(feature = "cidr")]
794        if let Ok(Some(v)) = row.try_get_cidr(&column) {
795            return T::from_postgres_cidr(v);
796        }
797
798        #[cfg(feature = "cidr")]
799        if let Ok(Some(v)) = row.try_get_macaddr(&column) {
800            return T::from_postgres_macaddr(v);
801        }
802
803        #[cfg(feature = "cidr")]
804        if let Ok(Some(v)) = row.try_get_macaddr8(&column) {
805            return T::from_postgres_macaddr8(v);
806        }
807
808        // Try geometric types
809        #[cfg(feature = "geo-types")]
810        if let Ok(Some(v)) = row.try_get_point(&column) {
811            return T::from_postgres_point(v);
812        }
813
814        #[cfg(feature = "geo-types")]
815        if let Ok(Some(v)) = row.try_get_linestring(&column) {
816            return T::from_postgres_linestring(v);
817        }
818
819        #[cfg(feature = "geo-types")]
820        if let Ok(Some(v)) = row.try_get_rect(&column) {
821            return T::from_postgres_rect(v);
822        }
823
824        // Try bit string types
825        #[cfg(feature = "bit-vec")]
826        if let Ok(Some(v)) = row.try_get_bitvec(&column) {
827            return T::from_postgres_bitvec(v);
828        }
829
830        // Try arrays
831        if let Ok(Some(values)) = row.try_get_array_bool(&column) {
832            return T::from_postgres_array(array_values(values));
833        }
834
835        if let Ok(Some(values)) = row.try_get_array_i16(&column) {
836            return T::from_postgres_array(array_values(values));
837        }
838
839        if let Ok(Some(values)) = row.try_get_array_i32(&column) {
840            return T::from_postgres_array(array_values(values));
841        }
842
843        if let Ok(Some(values)) = row.try_get_array_i64(&column) {
844            return T::from_postgres_array(array_values(values));
845        }
846
847        if let Ok(Some(values)) = row.try_get_array_f32(&column) {
848            return T::from_postgres_array(array_values(values));
849        }
850
851        if let Ok(Some(values)) = row.try_get_array_f64(&column) {
852            return T::from_postgres_array(array_values(values));
853        }
854
855        #[cfg(feature = "uuid")]
856        if let Ok(Some(values)) = row.try_get_array_uuid(&column) {
857            return T::from_postgres_array(array_values(values));
858        }
859
860        #[cfg(feature = "serde")]
861        if let Ok(Some(values)) = row.try_get_array_json(&column) {
862            return T::from_postgres_array(array_values(values));
863        }
864
865        #[cfg(feature = "chrono")]
866        if let Ok(Some(values)) = row.try_get_array_date(&column) {
867            return T::from_postgres_array(array_values(values));
868        }
869
870        #[cfg(feature = "chrono")]
871        if let Ok(Some(values)) = row.try_get_array_time(&column) {
872            return T::from_postgres_array(array_values(values));
873        }
874
875        #[cfg(feature = "chrono")]
876        if let Ok(Some(values)) = row.try_get_array_timestamp(&column) {
877            return T::from_postgres_array(array_values(values));
878        }
879
880        #[cfg(feature = "chrono")]
881        if let Ok(Some(values)) = row.try_get_array_timestamptz(&column) {
882            return T::from_postgres_array(array_values(values));
883        }
884
885        #[cfg(feature = "cidr")]
886        if let Ok(Some(values)) = row.try_get_array_inet(&column) {
887            return T::from_postgres_array(array_values(values));
888        }
889
890        #[cfg(feature = "cidr")]
891        if let Ok(Some(values)) = row.try_get_array_cidr(&column) {
892            return T::from_postgres_array(array_values(values));
893        }
894
895        #[cfg(feature = "cidr")]
896        if let Ok(Some(values)) = row.try_get_array_macaddr(&column) {
897            return T::from_postgres_array(array_values(values));
898        }
899
900        #[cfg(feature = "cidr")]
901        if let Ok(Some(values)) = row.try_get_array_macaddr8(&column) {
902            return T::from_postgres_array(array_values(values));
903        }
904
905        #[cfg(feature = "geo-types")]
906        if let Ok(Some(values)) = row.try_get_array_point(&column) {
907            return T::from_postgres_array(array_values(values));
908        }
909
910        #[cfg(feature = "geo-types")]
911        if let Ok(Some(values)) = row.try_get_array_linestring(&column) {
912            return T::from_postgres_array(array_values(values));
913        }
914
915        #[cfg(feature = "geo-types")]
916        if let Ok(Some(values)) = row.try_get_array_rect(&column) {
917            return T::from_postgres_array(array_values(values));
918        }
919
920        #[cfg(feature = "bit-vec")]
921        if let Ok(Some(values)) = row.try_get_array_bitvec(&column) {
922            return T::from_postgres_array(array_values(values));
923        }
924
925        if let Ok(Some(values)) = row.try_get_array_bytes(&column) {
926            return T::from_postgres_array(array_values(values));
927        }
928
929        if let Ok(Some(values)) = row.try_get_array_text(&column) {
930            return T::from_postgres_array(array_values(values));
931        }
932
933        // Check for NULL - if all type probes returned None/error, assume NULL
934        T::from_postgres_null()
935    }
936
937    /// Trait for column reference types (index or name)
938    trait ColumnRef: Copy {
939        fn to_index(&self) -> Option<usize>;
940        fn to_name(&self) -> Option<&str>;
941    }
942
943    impl ColumnRef for usize {
944        fn to_index(&self) -> Option<usize> {
945            Some(*self)
946        }
947        fn to_name(&self) -> Option<&str> {
948            None
949        }
950    }
951
952    impl ColumnRef for &str {
953        fn to_index(&self) -> Option<usize> {
954            None
955        }
956        fn to_name(&self) -> Option<&str> {
957            Some(*self)
958        }
959    }
960
961    fn array_values<T>(values: Vec<Option<T>>) -> Vec<PostgresValue<'static>>
962    where
963        T: Into<PostgresValue<'static>>,
964    {
965        values
966            .into_iter()
967            .map(|value| value.map(Into::into).unwrap_or(PostgresValue::Null))
968            .collect()
969    }
970
971    #[cfg(feature = "cidr")]
972    fn parse_mac<const N: usize>(value: &str) -> Option<[u8; N]> {
973        let mut bytes = [0u8; N];
974        let mut parts = value.split(':');
975
976        for slot in &mut bytes {
977            let part = parts.next()?;
978            if part.len() != 2 {
979                return None;
980            }
981            *slot = u8::from_str_radix(part, 16).ok()?;
982        }
983
984        if parts.next().is_some() {
985            return None;
986        }
987
988        Some(bytes)
989    }
990
991    #[cfg(feature = "cidr")]
992    fn parse_mac_array<const N: usize>(
993        values: Vec<Option<String>>,
994    ) -> Result<Vec<Option<[u8; N]>>, ()> {
995        let mut parsed = Vec::with_capacity(values.len());
996        for value in values {
997            match value {
998                Some(value) => {
999                    let parsed_value = parse_mac::<N>(&value).ok_or(())?;
1000                    parsed.push(Some(parsed_value));
1001                }
1002                None => parsed.push(None),
1003            }
1004        }
1005        Ok(parsed)
1006    }
1007
1008    /// Internal trait to abstract over postgres/tokio-postgres Row types
1009    trait PostgresRowLike {
1010        fn try_get_bool(&self, column: &impl ColumnRef) -> Result<Option<bool>, ()>;
1011        fn try_get_i16(&self, column: &impl ColumnRef) -> Result<Option<i16>, ()>;
1012        fn try_get_i32(&self, column: &impl ColumnRef) -> Result<Option<i32>, ()>;
1013        fn try_get_i64(&self, column: &impl ColumnRef) -> Result<Option<i64>, ()>;
1014        fn try_get_f32(&self, column: &impl ColumnRef) -> Result<Option<f32>, ()>;
1015        fn try_get_f64(&self, column: &impl ColumnRef) -> Result<Option<f64>, ()>;
1016        fn try_get_string(&self, column: &impl ColumnRef) -> Result<Option<String>, ()>;
1017        fn try_get_bytes(&self, column: &impl ColumnRef) -> Result<Option<Vec<u8>>, ()>;
1018        #[cfg(feature = "uuid")]
1019        fn try_get_uuid(&self, column: &impl ColumnRef) -> Result<Option<uuid::Uuid>, ()>;
1020        #[cfg(feature = "serde")]
1021        fn try_get_json(&self, column: &impl ColumnRef) -> Result<Option<serde_json::Value>, ()>;
1022        #[cfg(feature = "chrono")]
1023        fn try_get_date(&self, column: &impl ColumnRef) -> Result<Option<chrono::NaiveDate>, ()>;
1024        #[cfg(feature = "chrono")]
1025        fn try_get_time(&self, column: &impl ColumnRef) -> Result<Option<chrono::NaiveTime>, ()>;
1026        #[cfg(feature = "chrono")]
1027        fn try_get_timestamp(
1028            &self,
1029            column: &impl ColumnRef,
1030        ) -> Result<Option<chrono::NaiveDateTime>, ()>;
1031        #[cfg(feature = "chrono")]
1032        fn try_get_timestamptz(
1033            &self,
1034            column: &impl ColumnRef,
1035        ) -> Result<Option<chrono::DateTime<chrono::FixedOffset>>, ()>;
1036        #[cfg(feature = "cidr")]
1037        fn try_get_inet(&self, column: &impl ColumnRef) -> Result<Option<cidr::IpInet>, ()>;
1038        #[cfg(feature = "cidr")]
1039        fn try_get_cidr(&self, column: &impl ColumnRef) -> Result<Option<cidr::IpCidr>, ()>;
1040        #[cfg(feature = "cidr")]
1041        fn try_get_macaddr(&self, column: &impl ColumnRef) -> Result<Option<[u8; 6]>, ()>;
1042        #[cfg(feature = "cidr")]
1043        fn try_get_macaddr8(&self, column: &impl ColumnRef) -> Result<Option<[u8; 8]>, ()>;
1044        #[cfg(feature = "geo-types")]
1045        fn try_get_point(
1046            &self,
1047            column: &impl ColumnRef,
1048        ) -> Result<Option<geo_types::Point<f64>>, ()>;
1049        #[cfg(feature = "geo-types")]
1050        fn try_get_linestring(
1051            &self,
1052            column: &impl ColumnRef,
1053        ) -> Result<Option<geo_types::LineString<f64>>, ()>;
1054        #[cfg(feature = "geo-types")]
1055        fn try_get_rect(&self, column: &impl ColumnRef)
1056        -> Result<Option<geo_types::Rect<f64>>, ()>;
1057        #[cfg(feature = "bit-vec")]
1058        fn try_get_bitvec(&self, column: &impl ColumnRef) -> Result<Option<bit_vec::BitVec>, ()>;
1059
1060        fn try_get_array_bool(
1061            &self,
1062            column: &impl ColumnRef,
1063        ) -> Result<Option<Vec<Option<bool>>>, ()>;
1064        fn try_get_array_i16(
1065            &self,
1066            column: &impl ColumnRef,
1067        ) -> Result<Option<Vec<Option<i16>>>, ()>;
1068        fn try_get_array_i32(
1069            &self,
1070            column: &impl ColumnRef,
1071        ) -> Result<Option<Vec<Option<i32>>>, ()>;
1072        fn try_get_array_i64(
1073            &self,
1074            column: &impl ColumnRef,
1075        ) -> Result<Option<Vec<Option<i64>>>, ()>;
1076        fn try_get_array_f32(
1077            &self,
1078            column: &impl ColumnRef,
1079        ) -> Result<Option<Vec<Option<f32>>>, ()>;
1080        fn try_get_array_f64(
1081            &self,
1082            column: &impl ColumnRef,
1083        ) -> Result<Option<Vec<Option<f64>>>, ()>;
1084        fn try_get_array_text(
1085            &self,
1086            column: &impl ColumnRef,
1087        ) -> Result<Option<Vec<Option<String>>>, ()>;
1088        fn try_get_array_bytes(
1089            &self,
1090            column: &impl ColumnRef,
1091        ) -> Result<Option<Vec<Option<Vec<u8>>>>, ()>;
1092        #[cfg(feature = "uuid")]
1093        fn try_get_array_uuid(
1094            &self,
1095            column: &impl ColumnRef,
1096        ) -> Result<Option<Vec<Option<uuid::Uuid>>>, ()>;
1097        #[cfg(feature = "serde")]
1098        fn try_get_array_json(
1099            &self,
1100            column: &impl ColumnRef,
1101        ) -> Result<Option<Vec<Option<serde_json::Value>>>, ()>;
1102        #[cfg(feature = "chrono")]
1103        fn try_get_array_date(
1104            &self,
1105            column: &impl ColumnRef,
1106        ) -> Result<Option<Vec<Option<chrono::NaiveDate>>>, ()>;
1107        #[cfg(feature = "chrono")]
1108        fn try_get_array_time(
1109            &self,
1110            column: &impl ColumnRef,
1111        ) -> Result<Option<Vec<Option<chrono::NaiveTime>>>, ()>;
1112        #[cfg(feature = "chrono")]
1113        fn try_get_array_timestamp(
1114            &self,
1115            column: &impl ColumnRef,
1116        ) -> Result<Option<Vec<Option<chrono::NaiveDateTime>>>, ()>;
1117        #[cfg(feature = "chrono")]
1118        fn try_get_array_timestamptz(
1119            &self,
1120            column: &impl ColumnRef,
1121        ) -> Result<Option<Vec<Option<chrono::DateTime<chrono::FixedOffset>>>>, ()>;
1122        #[cfg(feature = "cidr")]
1123        fn try_get_array_inet(
1124            &self,
1125            column: &impl ColumnRef,
1126        ) -> Result<Option<Vec<Option<cidr::IpInet>>>, ()>;
1127        #[cfg(feature = "cidr")]
1128        fn try_get_array_cidr(
1129            &self,
1130            column: &impl ColumnRef,
1131        ) -> Result<Option<Vec<Option<cidr::IpCidr>>>, ()>;
1132        #[cfg(feature = "cidr")]
1133        fn try_get_array_macaddr(
1134            &self,
1135            column: &impl ColumnRef,
1136        ) -> Result<Option<Vec<Option<[u8; 6]>>>, ()>;
1137        #[cfg(feature = "cidr")]
1138        fn try_get_array_macaddr8(
1139            &self,
1140            column: &impl ColumnRef,
1141        ) -> Result<Option<Vec<Option<[u8; 8]>>>, ()>;
1142        #[cfg(feature = "geo-types")]
1143        fn try_get_array_point(
1144            &self,
1145            column: &impl ColumnRef,
1146        ) -> Result<Option<Vec<Option<geo_types::Point<f64>>>>, ()>;
1147        #[cfg(feature = "geo-types")]
1148        fn try_get_array_linestring(
1149            &self,
1150            column: &impl ColumnRef,
1151        ) -> Result<Option<Vec<Option<geo_types::LineString<f64>>>>, ()>;
1152        #[cfg(feature = "geo-types")]
1153        fn try_get_array_rect(
1154            &self,
1155            column: &impl ColumnRef,
1156        ) -> Result<Option<Vec<Option<geo_types::Rect<f64>>>>, ()>;
1157        #[cfg(feature = "bit-vec")]
1158        fn try_get_array_bitvec(
1159            &self,
1160            column: &impl ColumnRef,
1161        ) -> Result<Option<Vec<Option<bit_vec::BitVec>>>, ()>;
1162    }
1163
1164    // Use tokio_postgres when available, postgres when not
1165    #[cfg(feature = "tokio-postgres")]
1166    impl PostgresRowLike for tokio_postgres::Row {
1167        fn try_get_bool(&self, column: &impl ColumnRef) -> Result<Option<bool>, ()> {
1168            if let Some(idx) = column.to_index() {
1169                self.try_get::<_, Option<bool>>(idx).map_err(|_| ())
1170            } else if let Some(name) = column.to_name() {
1171                self.try_get::<_, Option<bool>>(name).map_err(|_| ())
1172            } else {
1173                Err(())
1174            }
1175        }
1176
1177        fn try_get_i16(&self, column: &impl ColumnRef) -> Result<Option<i16>, ()> {
1178            if let Some(idx) = column.to_index() {
1179                self.try_get::<_, Option<i16>>(idx).map_err(|_| ())
1180            } else if let Some(name) = column.to_name() {
1181                self.try_get::<_, Option<i16>>(name).map_err(|_| ())
1182            } else {
1183                Err(())
1184            }
1185        }
1186
1187        fn try_get_i32(&self, column: &impl ColumnRef) -> Result<Option<i32>, ()> {
1188            if let Some(idx) = column.to_index() {
1189                self.try_get::<_, Option<i32>>(idx).map_err(|_| ())
1190            } else if let Some(name) = column.to_name() {
1191                self.try_get::<_, Option<i32>>(name).map_err(|_| ())
1192            } else {
1193                Err(())
1194            }
1195        }
1196
1197        fn try_get_i64(&self, column: &impl ColumnRef) -> Result<Option<i64>, ()> {
1198            if let Some(idx) = column.to_index() {
1199                self.try_get::<_, Option<i64>>(idx).map_err(|_| ())
1200            } else if let Some(name) = column.to_name() {
1201                self.try_get::<_, Option<i64>>(name).map_err(|_| ())
1202            } else {
1203                Err(())
1204            }
1205        }
1206
1207        fn try_get_f32(&self, column: &impl ColumnRef) -> Result<Option<f32>, ()> {
1208            if let Some(idx) = column.to_index() {
1209                self.try_get::<_, Option<f32>>(idx).map_err(|_| ())
1210            } else if let Some(name) = column.to_name() {
1211                self.try_get::<_, Option<f32>>(name).map_err(|_| ())
1212            } else {
1213                Err(())
1214            }
1215        }
1216
1217        fn try_get_f64(&self, column: &impl ColumnRef) -> Result<Option<f64>, ()> {
1218            if let Some(idx) = column.to_index() {
1219                self.try_get::<_, Option<f64>>(idx).map_err(|_| ())
1220            } else if let Some(name) = column.to_name() {
1221                self.try_get::<_, Option<f64>>(name).map_err(|_| ())
1222            } else {
1223                Err(())
1224            }
1225        }
1226
1227        fn try_get_string(&self, column: &impl ColumnRef) -> Result<Option<String>, ()> {
1228            if let Some(idx) = column.to_index() {
1229                self.try_get::<_, Option<String>>(idx).map_err(|_| ())
1230            } else if let Some(name) = column.to_name() {
1231                self.try_get::<_, Option<String>>(name).map_err(|_| ())
1232            } else {
1233                Err(())
1234            }
1235        }
1236
1237        fn try_get_bytes(&self, column: &impl ColumnRef) -> Result<Option<Vec<u8>>, ()> {
1238            if let Some(idx) = column.to_index() {
1239                self.try_get::<_, Option<Vec<u8>>>(idx).map_err(|_| ())
1240            } else if let Some(name) = column.to_name() {
1241                self.try_get::<_, Option<Vec<u8>>>(name).map_err(|_| ())
1242            } else {
1243                Err(())
1244            }
1245        }
1246
1247        #[cfg(feature = "uuid")]
1248        fn try_get_uuid(&self, column: &impl ColumnRef) -> Result<Option<uuid::Uuid>, ()> {
1249            if let Some(idx) = column.to_index() {
1250                self.try_get::<_, Option<uuid::Uuid>>(idx).map_err(|_| ())
1251            } else if let Some(name) = column.to_name() {
1252                self.try_get::<_, Option<uuid::Uuid>>(name).map_err(|_| ())
1253            } else {
1254                Err(())
1255            }
1256        }
1257
1258        #[cfg(feature = "serde")]
1259        fn try_get_json(&self, column: &impl ColumnRef) -> Result<Option<serde_json::Value>, ()> {
1260            if let Some(idx) = column.to_index() {
1261                self.try_get::<_, Option<serde_json::Value>>(idx)
1262                    .map_err(|_| ())
1263            } else if let Some(name) = column.to_name() {
1264                self.try_get::<_, Option<serde_json::Value>>(name)
1265                    .map_err(|_| ())
1266            } else {
1267                Err(())
1268            }
1269        }
1270
1271        #[cfg(feature = "chrono")]
1272        fn try_get_date(&self, column: &impl ColumnRef) -> Result<Option<chrono::NaiveDate>, ()> {
1273            if let Some(idx) = column.to_index() {
1274                self.try_get::<_, Option<chrono::NaiveDate>>(idx)
1275                    .map_err(|_| ())
1276            } else if let Some(name) = column.to_name() {
1277                self.try_get::<_, Option<chrono::NaiveDate>>(name)
1278                    .map_err(|_| ())
1279            } else {
1280                Err(())
1281            }
1282        }
1283
1284        #[cfg(feature = "chrono")]
1285        fn try_get_time(&self, column: &impl ColumnRef) -> Result<Option<chrono::NaiveTime>, ()> {
1286            if let Some(idx) = column.to_index() {
1287                self.try_get::<_, Option<chrono::NaiveTime>>(idx)
1288                    .map_err(|_| ())
1289            } else if let Some(name) = column.to_name() {
1290                self.try_get::<_, Option<chrono::NaiveTime>>(name)
1291                    .map_err(|_| ())
1292            } else {
1293                Err(())
1294            }
1295        }
1296
1297        #[cfg(feature = "chrono")]
1298        fn try_get_timestamp(
1299            &self,
1300            column: &impl ColumnRef,
1301        ) -> Result<Option<chrono::NaiveDateTime>, ()> {
1302            if let Some(idx) = column.to_index() {
1303                self.try_get::<_, Option<chrono::NaiveDateTime>>(idx)
1304                    .map_err(|_| ())
1305            } else if let Some(name) = column.to_name() {
1306                self.try_get::<_, Option<chrono::NaiveDateTime>>(name)
1307                    .map_err(|_| ())
1308            } else {
1309                Err(())
1310            }
1311        }
1312
1313        #[cfg(feature = "chrono")]
1314        fn try_get_timestamptz(
1315            &self,
1316            column: &impl ColumnRef,
1317        ) -> Result<Option<chrono::DateTime<chrono::FixedOffset>>, ()> {
1318            if let Some(idx) = column.to_index() {
1319                self.try_get::<_, Option<chrono::DateTime<chrono::FixedOffset>>>(idx)
1320                    .map_err(|_| ())
1321            } else if let Some(name) = column.to_name() {
1322                self.try_get::<_, Option<chrono::DateTime<chrono::FixedOffset>>>(name)
1323                    .map_err(|_| ())
1324            } else {
1325                Err(())
1326            }
1327        }
1328
1329        #[cfg(feature = "cidr")]
1330        fn try_get_inet(&self, column: &impl ColumnRef) -> Result<Option<cidr::IpInet>, ()> {
1331            if let Some(idx) = column.to_index() {
1332                self.try_get::<_, Option<cidr::IpInet>>(idx).map_err(|_| ())
1333            } else if let Some(name) = column.to_name() {
1334                self.try_get::<_, Option<cidr::IpInet>>(name)
1335                    .map_err(|_| ())
1336            } else {
1337                Err(())
1338            }
1339        }
1340
1341        #[cfg(feature = "cidr")]
1342        fn try_get_cidr(&self, column: &impl ColumnRef) -> Result<Option<cidr::IpCidr>, ()> {
1343            if let Some(idx) = column.to_index() {
1344                self.try_get::<_, Option<cidr::IpCidr>>(idx).map_err(|_| ())
1345            } else if let Some(name) = column.to_name() {
1346                self.try_get::<_, Option<cidr::IpCidr>>(name)
1347                    .map_err(|_| ())
1348            } else {
1349                Err(())
1350            }
1351        }
1352
1353        #[cfg(feature = "cidr")]
1354        fn try_get_macaddr(&self, column: &impl ColumnRef) -> Result<Option<[u8; 6]>, ()> {
1355            match self.try_get_string(column) {
1356                Ok(Some(value)) => parse_mac::<6>(&value).ok_or(()).map(Some),
1357                Ok(None) => Ok(None),
1358                Err(()) => Err(()),
1359            }
1360        }
1361
1362        #[cfg(feature = "cidr")]
1363        fn try_get_macaddr8(&self, column: &impl ColumnRef) -> Result<Option<[u8; 8]>, ()> {
1364            match self.try_get_string(column) {
1365                Ok(Some(value)) => parse_mac::<8>(&value).ok_or(()).map(Some),
1366                Ok(None) => Ok(None),
1367                Err(()) => Err(()),
1368            }
1369        }
1370
1371        #[cfg(feature = "geo-types")]
1372        fn try_get_point(
1373            &self,
1374            column: &impl ColumnRef,
1375        ) -> Result<Option<geo_types::Point<f64>>, ()> {
1376            if let Some(idx) = column.to_index() {
1377                self.try_get::<_, Option<geo_types::Point<f64>>>(idx)
1378                    .map_err(|_| ())
1379            } else if let Some(name) = column.to_name() {
1380                self.try_get::<_, Option<geo_types::Point<f64>>>(name)
1381                    .map_err(|_| ())
1382            } else {
1383                Err(())
1384            }
1385        }
1386
1387        #[cfg(feature = "geo-types")]
1388        fn try_get_linestring(
1389            &self,
1390            column: &impl ColumnRef,
1391        ) -> Result<Option<geo_types::LineString<f64>>, ()> {
1392            if let Some(idx) = column.to_index() {
1393                self.try_get::<_, Option<geo_types::LineString<f64>>>(idx)
1394                    .map_err(|_| ())
1395            } else if let Some(name) = column.to_name() {
1396                self.try_get::<_, Option<geo_types::LineString<f64>>>(name)
1397                    .map_err(|_| ())
1398            } else {
1399                Err(())
1400            }
1401        }
1402
1403        #[cfg(feature = "geo-types")]
1404        fn try_get_rect(
1405            &self,
1406            column: &impl ColumnRef,
1407        ) -> Result<Option<geo_types::Rect<f64>>, ()> {
1408            if let Some(idx) = column.to_index() {
1409                self.try_get::<_, Option<geo_types::Rect<f64>>>(idx)
1410                    .map_err(|_| ())
1411            } else if let Some(name) = column.to_name() {
1412                self.try_get::<_, Option<geo_types::Rect<f64>>>(name)
1413                    .map_err(|_| ())
1414            } else {
1415                Err(())
1416            }
1417        }
1418
1419        #[cfg(feature = "bit-vec")]
1420        fn try_get_bitvec(&self, column: &impl ColumnRef) -> Result<Option<bit_vec::BitVec>, ()> {
1421            if let Some(idx) = column.to_index() {
1422                self.try_get::<_, Option<bit_vec::BitVec>>(idx)
1423                    .map_err(|_| ())
1424            } else if let Some(name) = column.to_name() {
1425                self.try_get::<_, Option<bit_vec::BitVec>>(name)
1426                    .map_err(|_| ())
1427            } else {
1428                Err(())
1429            }
1430        }
1431
1432        fn try_get_array_bool(
1433            &self,
1434            column: &impl ColumnRef,
1435        ) -> Result<Option<Vec<Option<bool>>>, ()> {
1436            if let Some(idx) = column.to_index() {
1437                self.try_get::<_, Option<Vec<Option<bool>>>>(idx)
1438                    .map_err(|_| ())
1439            } else if let Some(name) = column.to_name() {
1440                self.try_get::<_, Option<Vec<Option<bool>>>>(name)
1441                    .map_err(|_| ())
1442            } else {
1443                Err(())
1444            }
1445        }
1446
1447        fn try_get_array_i16(
1448            &self,
1449            column: &impl ColumnRef,
1450        ) -> Result<Option<Vec<Option<i16>>>, ()> {
1451            if let Some(idx) = column.to_index() {
1452                self.try_get::<_, Option<Vec<Option<i16>>>>(idx)
1453                    .map_err(|_| ())
1454            } else if let Some(name) = column.to_name() {
1455                self.try_get::<_, Option<Vec<Option<i16>>>>(name)
1456                    .map_err(|_| ())
1457            } else {
1458                Err(())
1459            }
1460        }
1461
1462        fn try_get_array_i32(
1463            &self,
1464            column: &impl ColumnRef,
1465        ) -> Result<Option<Vec<Option<i32>>>, ()> {
1466            if let Some(idx) = column.to_index() {
1467                self.try_get::<_, Option<Vec<Option<i32>>>>(idx)
1468                    .map_err(|_| ())
1469            } else if let Some(name) = column.to_name() {
1470                self.try_get::<_, Option<Vec<Option<i32>>>>(name)
1471                    .map_err(|_| ())
1472            } else {
1473                Err(())
1474            }
1475        }
1476
1477        fn try_get_array_i64(
1478            &self,
1479            column: &impl ColumnRef,
1480        ) -> Result<Option<Vec<Option<i64>>>, ()> {
1481            if let Some(idx) = column.to_index() {
1482                self.try_get::<_, Option<Vec<Option<i64>>>>(idx)
1483                    .map_err(|_| ())
1484            } else if let Some(name) = column.to_name() {
1485                self.try_get::<_, Option<Vec<Option<i64>>>>(name)
1486                    .map_err(|_| ())
1487            } else {
1488                Err(())
1489            }
1490        }
1491
1492        fn try_get_array_f32(
1493            &self,
1494            column: &impl ColumnRef,
1495        ) -> Result<Option<Vec<Option<f32>>>, ()> {
1496            if let Some(idx) = column.to_index() {
1497                self.try_get::<_, Option<Vec<Option<f32>>>>(idx)
1498                    .map_err(|_| ())
1499            } else if let Some(name) = column.to_name() {
1500                self.try_get::<_, Option<Vec<Option<f32>>>>(name)
1501                    .map_err(|_| ())
1502            } else {
1503                Err(())
1504            }
1505        }
1506
1507        fn try_get_array_f64(
1508            &self,
1509            column: &impl ColumnRef,
1510        ) -> Result<Option<Vec<Option<f64>>>, ()> {
1511            if let Some(idx) = column.to_index() {
1512                self.try_get::<_, Option<Vec<Option<f64>>>>(idx)
1513                    .map_err(|_| ())
1514            } else if let Some(name) = column.to_name() {
1515                self.try_get::<_, Option<Vec<Option<f64>>>>(name)
1516                    .map_err(|_| ())
1517            } else {
1518                Err(())
1519            }
1520        }
1521
1522        fn try_get_array_text(
1523            &self,
1524            column: &impl ColumnRef,
1525        ) -> Result<Option<Vec<Option<String>>>, ()> {
1526            if let Some(idx) = column.to_index() {
1527                self.try_get::<_, Option<Vec<Option<String>>>>(idx)
1528                    .map_err(|_| ())
1529            } else if let Some(name) = column.to_name() {
1530                self.try_get::<_, Option<Vec<Option<String>>>>(name)
1531                    .map_err(|_| ())
1532            } else {
1533                Err(())
1534            }
1535        }
1536
1537        fn try_get_array_bytes(
1538            &self,
1539            column: &impl ColumnRef,
1540        ) -> Result<Option<Vec<Option<Vec<u8>>>>, ()> {
1541            if let Some(idx) = column.to_index() {
1542                self.try_get::<_, Option<Vec<Option<Vec<u8>>>>>(idx)
1543                    .map_err(|_| ())
1544            } else if let Some(name) = column.to_name() {
1545                self.try_get::<_, Option<Vec<Option<Vec<u8>>>>>(name)
1546                    .map_err(|_| ())
1547            } else {
1548                Err(())
1549            }
1550        }
1551
1552        #[cfg(feature = "uuid")]
1553        fn try_get_array_uuid(
1554            &self,
1555            column: &impl ColumnRef,
1556        ) -> Result<Option<Vec<Option<uuid::Uuid>>>, ()> {
1557            if let Some(idx) = column.to_index() {
1558                self.try_get::<_, Option<Vec<Option<uuid::Uuid>>>>(idx)
1559                    .map_err(|_| ())
1560            } else if let Some(name) = column.to_name() {
1561                self.try_get::<_, Option<Vec<Option<uuid::Uuid>>>>(name)
1562                    .map_err(|_| ())
1563            } else {
1564                Err(())
1565            }
1566        }
1567
1568        #[cfg(feature = "serde")]
1569        fn try_get_array_json(
1570            &self,
1571            column: &impl ColumnRef,
1572        ) -> Result<Option<Vec<Option<serde_json::Value>>>, ()> {
1573            if let Some(idx) = column.to_index() {
1574                self.try_get::<_, Option<Vec<Option<serde_json::Value>>>>(idx)
1575                    .map_err(|_| ())
1576            } else if let Some(name) = column.to_name() {
1577                self.try_get::<_, Option<Vec<Option<serde_json::Value>>>>(name)
1578                    .map_err(|_| ())
1579            } else {
1580                Err(())
1581            }
1582        }
1583
1584        #[cfg(feature = "chrono")]
1585        fn try_get_array_date(
1586            &self,
1587            column: &impl ColumnRef,
1588        ) -> Result<Option<Vec<Option<chrono::NaiveDate>>>, ()> {
1589            if let Some(idx) = column.to_index() {
1590                self.try_get::<_, Option<Vec<Option<chrono::NaiveDate>>>>(idx)
1591                    .map_err(|_| ())
1592            } else if let Some(name) = column.to_name() {
1593                self.try_get::<_, Option<Vec<Option<chrono::NaiveDate>>>>(name)
1594                    .map_err(|_| ())
1595            } else {
1596                Err(())
1597            }
1598        }
1599
1600        #[cfg(feature = "chrono")]
1601        fn try_get_array_time(
1602            &self,
1603            column: &impl ColumnRef,
1604        ) -> Result<Option<Vec<Option<chrono::NaiveTime>>>, ()> {
1605            if let Some(idx) = column.to_index() {
1606                self.try_get::<_, Option<Vec<Option<chrono::NaiveTime>>>>(idx)
1607                    .map_err(|_| ())
1608            } else if let Some(name) = column.to_name() {
1609                self.try_get::<_, Option<Vec<Option<chrono::NaiveTime>>>>(name)
1610                    .map_err(|_| ())
1611            } else {
1612                Err(())
1613            }
1614        }
1615
1616        #[cfg(feature = "chrono")]
1617        fn try_get_array_timestamp(
1618            &self,
1619            column: &impl ColumnRef,
1620        ) -> Result<Option<Vec<Option<chrono::NaiveDateTime>>>, ()> {
1621            if let Some(idx) = column.to_index() {
1622                self.try_get::<_, Option<Vec<Option<chrono::NaiveDateTime>>>>(idx)
1623                    .map_err(|_| ())
1624            } else if let Some(name) = column.to_name() {
1625                self.try_get::<_, Option<Vec<Option<chrono::NaiveDateTime>>>>(name)
1626                    .map_err(|_| ())
1627            } else {
1628                Err(())
1629            }
1630        }
1631
1632        #[cfg(feature = "chrono")]
1633        fn try_get_array_timestamptz(
1634            &self,
1635            column: &impl ColumnRef,
1636        ) -> Result<Option<Vec<Option<chrono::DateTime<chrono::FixedOffset>>>>, ()> {
1637            if let Some(idx) = column.to_index() {
1638                self.try_get::<_, Option<Vec<Option<chrono::DateTime<chrono::FixedOffset>>>>>(idx)
1639                    .map_err(|_| ())
1640            } else if let Some(name) = column.to_name() {
1641                self.try_get::<_, Option<Vec<Option<chrono::DateTime<chrono::FixedOffset>>>>>(name)
1642                    .map_err(|_| ())
1643            } else {
1644                Err(())
1645            }
1646        }
1647
1648        #[cfg(feature = "cidr")]
1649        fn try_get_array_inet(
1650            &self,
1651            column: &impl ColumnRef,
1652        ) -> Result<Option<Vec<Option<cidr::IpInet>>>, ()> {
1653            if let Some(idx) = column.to_index() {
1654                self.try_get::<_, Option<Vec<Option<cidr::IpInet>>>>(idx)
1655                    .map_err(|_| ())
1656            } else if let Some(name) = column.to_name() {
1657                self.try_get::<_, Option<Vec<Option<cidr::IpInet>>>>(name)
1658                    .map_err(|_| ())
1659            } else {
1660                Err(())
1661            }
1662        }
1663
1664        #[cfg(feature = "cidr")]
1665        fn try_get_array_cidr(
1666            &self,
1667            column: &impl ColumnRef,
1668        ) -> Result<Option<Vec<Option<cidr::IpCidr>>>, ()> {
1669            if let Some(idx) = column.to_index() {
1670                self.try_get::<_, Option<Vec<Option<cidr::IpCidr>>>>(idx)
1671                    .map_err(|_| ())
1672            } else if let Some(name) = column.to_name() {
1673                self.try_get::<_, Option<Vec<Option<cidr::IpCidr>>>>(name)
1674                    .map_err(|_| ())
1675            } else {
1676                Err(())
1677            }
1678        }
1679
1680        #[cfg(feature = "cidr")]
1681        fn try_get_array_macaddr(
1682            &self,
1683            column: &impl ColumnRef,
1684        ) -> Result<Option<Vec<Option<[u8; 6]>>>, ()> {
1685            match self.try_get_array_text(column) {
1686                Ok(Some(values)) => parse_mac_array::<6>(values).map(Some),
1687                Ok(None) => Ok(None),
1688                Err(()) => Err(()),
1689            }
1690        }
1691
1692        #[cfg(feature = "cidr")]
1693        fn try_get_array_macaddr8(
1694            &self,
1695            column: &impl ColumnRef,
1696        ) -> Result<Option<Vec<Option<[u8; 8]>>>, ()> {
1697            match self.try_get_array_text(column) {
1698                Ok(Some(values)) => parse_mac_array::<8>(values).map(Some),
1699                Ok(None) => Ok(None),
1700                Err(()) => Err(()),
1701            }
1702        }
1703
1704        #[cfg(feature = "geo-types")]
1705        fn try_get_array_point(
1706            &self,
1707            column: &impl ColumnRef,
1708        ) -> Result<Option<Vec<Option<geo_types::Point<f64>>>>, ()> {
1709            if let Some(idx) = column.to_index() {
1710                self.try_get::<_, Option<Vec<Option<geo_types::Point<f64>>>>>(idx)
1711                    .map_err(|_| ())
1712            } else if let Some(name) = column.to_name() {
1713                self.try_get::<_, Option<Vec<Option<geo_types::Point<f64>>>>>(name)
1714                    .map_err(|_| ())
1715            } else {
1716                Err(())
1717            }
1718        }
1719
1720        #[cfg(feature = "geo-types")]
1721        fn try_get_array_linestring(
1722            &self,
1723            column: &impl ColumnRef,
1724        ) -> Result<Option<Vec<Option<geo_types::LineString<f64>>>>, ()> {
1725            if let Some(idx) = column.to_index() {
1726                self.try_get::<_, Option<Vec<Option<geo_types::LineString<f64>>>>>(idx)
1727                    .map_err(|_| ())
1728            } else if let Some(name) = column.to_name() {
1729                self.try_get::<_, Option<Vec<Option<geo_types::LineString<f64>>>>>(name)
1730                    .map_err(|_| ())
1731            } else {
1732                Err(())
1733            }
1734        }
1735
1736        #[cfg(feature = "geo-types")]
1737        fn try_get_array_rect(
1738            &self,
1739            column: &impl ColumnRef,
1740        ) -> Result<Option<Vec<Option<geo_types::Rect<f64>>>>, ()> {
1741            if let Some(idx) = column.to_index() {
1742                self.try_get::<_, Option<Vec<Option<geo_types::Rect<f64>>>>>(idx)
1743                    .map_err(|_| ())
1744            } else if let Some(name) = column.to_name() {
1745                self.try_get::<_, Option<Vec<Option<geo_types::Rect<f64>>>>>(name)
1746                    .map_err(|_| ())
1747            } else {
1748                Err(())
1749            }
1750        }
1751
1752        #[cfg(feature = "bit-vec")]
1753        fn try_get_array_bitvec(
1754            &self,
1755            column: &impl ColumnRef,
1756        ) -> Result<Option<Vec<Option<bit_vec::BitVec>>>, ()> {
1757            if let Some(idx) = column.to_index() {
1758                self.try_get::<_, Option<Vec<Option<bit_vec::BitVec>>>>(idx)
1759                    .map_err(|_| ())
1760            } else if let Some(name) = column.to_name() {
1761                self.try_get::<_, Option<Vec<Option<bit_vec::BitVec>>>>(name)
1762                    .map_err(|_| ())
1763            } else {
1764                Err(())
1765            }
1766        }
1767    }
1768
1769    #[cfg(feature = "tokio-postgres")]
1770    impl DrizzleRow for tokio_postgres::Row {
1771        fn get_column<T: FromPostgresValue>(&self, idx: usize) -> Result<T, DrizzleError> {
1772            convert_column(self, idx)
1773        }
1774
1775        fn get_column_by_name<T: FromPostgresValue>(&self, name: &str) -> Result<T, DrizzleError> {
1776            convert_column(self, name)
1777        }
1778    }
1779
1780    // postgres::Row is a re-export of tokio_postgres::Row, so when both features
1781    // are enabled, this implementation applies to both. When only postgres-sync
1782    // is enabled, we need a separate implementation.
1783    #[cfg(all(feature = "postgres-sync", not(feature = "tokio-postgres")))]
1784    impl PostgresRowLike for postgres::Row {
1785        fn try_get_bool(&self, column: &impl ColumnRef) -> Result<Option<bool>, ()> {
1786            if let Some(idx) = column.to_index() {
1787                self.try_get::<_, Option<bool>>(idx).map_err(|_| ())
1788            } else if let Some(name) = column.to_name() {
1789                self.try_get::<_, Option<bool>>(name).map_err(|_| ())
1790            } else {
1791                Err(())
1792            }
1793        }
1794
1795        fn try_get_i16(&self, column: &impl ColumnRef) -> Result<Option<i16>, ()> {
1796            if let Some(idx) = column.to_index() {
1797                self.try_get::<_, Option<i16>>(idx).map_err(|_| ())
1798            } else if let Some(name) = column.to_name() {
1799                self.try_get::<_, Option<i16>>(name).map_err(|_| ())
1800            } else {
1801                Err(())
1802            }
1803        }
1804
1805        fn try_get_i32(&self, column: &impl ColumnRef) -> Result<Option<i32>, ()> {
1806            if let Some(idx) = column.to_index() {
1807                self.try_get::<_, Option<i32>>(idx).map_err(|_| ())
1808            } else if let Some(name) = column.to_name() {
1809                self.try_get::<_, Option<i32>>(name).map_err(|_| ())
1810            } else {
1811                Err(())
1812            }
1813        }
1814
1815        fn try_get_i64(&self, column: &impl ColumnRef) -> Result<Option<i64>, ()> {
1816            if let Some(idx) = column.to_index() {
1817                self.try_get::<_, Option<i64>>(idx).map_err(|_| ())
1818            } else if let Some(name) = column.to_name() {
1819                self.try_get::<_, Option<i64>>(name).map_err(|_| ())
1820            } else {
1821                Err(())
1822            }
1823        }
1824
1825        fn try_get_f32(&self, column: &impl ColumnRef) -> Result<Option<f32>, ()> {
1826            if let Some(idx) = column.to_index() {
1827                self.try_get::<_, Option<f32>>(idx).map_err(|_| ())
1828            } else if let Some(name) = column.to_name() {
1829                self.try_get::<_, Option<f32>>(name).map_err(|_| ())
1830            } else {
1831                Err(())
1832            }
1833        }
1834
1835        fn try_get_f64(&self, column: &impl ColumnRef) -> Result<Option<f64>, ()> {
1836            if let Some(idx) = column.to_index() {
1837                self.try_get::<_, Option<f64>>(idx).map_err(|_| ())
1838            } else if let Some(name) = column.to_name() {
1839                self.try_get::<_, Option<f64>>(name).map_err(|_| ())
1840            } else {
1841                Err(())
1842            }
1843        }
1844
1845        fn try_get_string(&self, column: &impl ColumnRef) -> Result<Option<String>, ()> {
1846            if let Some(idx) = column.to_index() {
1847                self.try_get::<_, Option<String>>(idx).map_err(|_| ())
1848            } else if let Some(name) = column.to_name() {
1849                self.try_get::<_, Option<String>>(name).map_err(|_| ())
1850            } else {
1851                Err(())
1852            }
1853        }
1854
1855        fn try_get_bytes(&self, column: &impl ColumnRef) -> Result<Option<Vec<u8>>, ()> {
1856            if let Some(idx) = column.to_index() {
1857                self.try_get::<_, Option<Vec<u8>>>(idx).map_err(|_| ())
1858            } else if let Some(name) = column.to_name() {
1859                self.try_get::<_, Option<Vec<u8>>>(name).map_err(|_| ())
1860            } else {
1861                Err(())
1862            }
1863        }
1864
1865        #[cfg(feature = "uuid")]
1866        fn try_get_uuid(&self, column: &impl ColumnRef) -> Result<Option<uuid::Uuid>, ()> {
1867            if let Some(idx) = column.to_index() {
1868                self.try_get::<_, Option<uuid::Uuid>>(idx).map_err(|_| ())
1869            } else if let Some(name) = column.to_name() {
1870                self.try_get::<_, Option<uuid::Uuid>>(name).map_err(|_| ())
1871            } else {
1872                Err(())
1873            }
1874        }
1875
1876        #[cfg(feature = "serde")]
1877        fn try_get_json(&self, column: &impl ColumnRef) -> Result<Option<serde_json::Value>, ()> {
1878            if let Some(idx) = column.to_index() {
1879                self.try_get::<_, Option<serde_json::Value>>(idx)
1880                    .map_err(|_| ())
1881            } else if let Some(name) = column.to_name() {
1882                self.try_get::<_, Option<serde_json::Value>>(name)
1883                    .map_err(|_| ())
1884            } else {
1885                Err(())
1886            }
1887        }
1888
1889        #[cfg(feature = "chrono")]
1890        fn try_get_date(&self, column: &impl ColumnRef) -> Result<Option<chrono::NaiveDate>, ()> {
1891            if let Some(idx) = column.to_index() {
1892                self.try_get::<_, Option<chrono::NaiveDate>>(idx)
1893                    .map_err(|_| ())
1894            } else if let Some(name) = column.to_name() {
1895                self.try_get::<_, Option<chrono::NaiveDate>>(name)
1896                    .map_err(|_| ())
1897            } else {
1898                Err(())
1899            }
1900        }
1901
1902        #[cfg(feature = "chrono")]
1903        fn try_get_time(&self, column: &impl ColumnRef) -> Result<Option<chrono::NaiveTime>, ()> {
1904            if let Some(idx) = column.to_index() {
1905                self.try_get::<_, Option<chrono::NaiveTime>>(idx)
1906                    .map_err(|_| ())
1907            } else if let Some(name) = column.to_name() {
1908                self.try_get::<_, Option<chrono::NaiveTime>>(name)
1909                    .map_err(|_| ())
1910            } else {
1911                Err(())
1912            }
1913        }
1914
1915        #[cfg(feature = "chrono")]
1916        fn try_get_timestamp(
1917            &self,
1918            column: &impl ColumnRef,
1919        ) -> Result<Option<chrono::NaiveDateTime>, ()> {
1920            if let Some(idx) = column.to_index() {
1921                self.try_get::<_, Option<chrono::NaiveDateTime>>(idx)
1922                    .map_err(|_| ())
1923            } else if let Some(name) = column.to_name() {
1924                self.try_get::<_, Option<chrono::NaiveDateTime>>(name)
1925                    .map_err(|_| ())
1926            } else {
1927                Err(())
1928            }
1929        }
1930
1931        #[cfg(feature = "chrono")]
1932        fn try_get_timestamptz(
1933            &self,
1934            column: &impl ColumnRef,
1935        ) -> Result<Option<chrono::DateTime<chrono::FixedOffset>>, ()> {
1936            if let Some(idx) = column.to_index() {
1937                self.try_get::<_, Option<chrono::DateTime<chrono::FixedOffset>>>(idx)
1938                    .map_err(|_| ())
1939            } else if let Some(name) = column.to_name() {
1940                self.try_get::<_, Option<chrono::DateTime<chrono::FixedOffset>>>(name)
1941                    .map_err(|_| ())
1942            } else {
1943                Err(())
1944            }
1945        }
1946
1947        #[cfg(feature = "cidr")]
1948        fn try_get_inet(&self, column: &impl ColumnRef) -> Result<Option<cidr::IpInet>, ()> {
1949            if let Some(idx) = column.to_index() {
1950                self.try_get::<_, Option<cidr::IpInet>>(idx).map_err(|_| ())
1951            } else if let Some(name) = column.to_name() {
1952                self.try_get::<_, Option<cidr::IpInet>>(name)
1953                    .map_err(|_| ())
1954            } else {
1955                Err(())
1956            }
1957        }
1958
1959        #[cfg(feature = "cidr")]
1960        fn try_get_cidr(&self, column: &impl ColumnRef) -> Result<Option<cidr::IpCidr>, ()> {
1961            if let Some(idx) = column.to_index() {
1962                self.try_get::<_, Option<cidr::IpCidr>>(idx).map_err(|_| ())
1963            } else if let Some(name) = column.to_name() {
1964                self.try_get::<_, Option<cidr::IpCidr>>(name)
1965                    .map_err(|_| ())
1966            } else {
1967                Err(())
1968            }
1969        }
1970
1971        #[cfg(feature = "cidr")]
1972        fn try_get_macaddr(&self, column: &impl ColumnRef) -> Result<Option<[u8; 6]>, ()> {
1973            match self.try_get_string(column) {
1974                Ok(Some(value)) => parse_mac::<6>(&value).ok_or(()).map(Some),
1975                Ok(None) => Ok(None),
1976                Err(()) => Err(()),
1977            }
1978        }
1979
1980        #[cfg(feature = "cidr")]
1981        fn try_get_macaddr8(&self, column: &impl ColumnRef) -> Result<Option<[u8; 8]>, ()> {
1982            match self.try_get_string(column) {
1983                Ok(Some(value)) => parse_mac::<8>(&value).ok_or(()).map(Some),
1984                Ok(None) => Ok(None),
1985                Err(()) => Err(()),
1986            }
1987        }
1988
1989        #[cfg(feature = "geo-types")]
1990        fn try_get_point(
1991            &self,
1992            column: &impl ColumnRef,
1993        ) -> Result<Option<geo_types::Point<f64>>, ()> {
1994            if let Some(idx) = column.to_index() {
1995                self.try_get::<_, Option<geo_types::Point<f64>>>(idx)
1996                    .map_err(|_| ())
1997            } else if let Some(name) = column.to_name() {
1998                self.try_get::<_, Option<geo_types::Point<f64>>>(name)
1999                    .map_err(|_| ())
2000            } else {
2001                Err(())
2002            }
2003        }
2004
2005        #[cfg(feature = "geo-types")]
2006        fn try_get_linestring(
2007            &self,
2008            column: &impl ColumnRef,
2009        ) -> Result<Option<geo_types::LineString<f64>>, ()> {
2010            if let Some(idx) = column.to_index() {
2011                self.try_get::<_, Option<geo_types::LineString<f64>>>(idx)
2012                    .map_err(|_| ())
2013            } else if let Some(name) = column.to_name() {
2014                self.try_get::<_, Option<geo_types::LineString<f64>>>(name)
2015                    .map_err(|_| ())
2016            } else {
2017                Err(())
2018            }
2019        }
2020
2021        #[cfg(feature = "geo-types")]
2022        fn try_get_rect(
2023            &self,
2024            column: &impl ColumnRef,
2025        ) -> Result<Option<geo_types::Rect<f64>>, ()> {
2026            if let Some(idx) = column.to_index() {
2027                self.try_get::<_, Option<geo_types::Rect<f64>>>(idx)
2028                    .map_err(|_| ())
2029            } else if let Some(name) = column.to_name() {
2030                self.try_get::<_, Option<geo_types::Rect<f64>>>(name)
2031                    .map_err(|_| ())
2032            } else {
2033                Err(())
2034            }
2035        }
2036
2037        #[cfg(feature = "bit-vec")]
2038        fn try_get_bitvec(&self, column: &impl ColumnRef) -> Result<Option<bit_vec::BitVec>, ()> {
2039            if let Some(idx) = column.to_index() {
2040                self.try_get::<_, Option<bit_vec::BitVec>>(idx)
2041                    .map_err(|_| ())
2042            } else if let Some(name) = column.to_name() {
2043                self.try_get::<_, Option<bit_vec::BitVec>>(name)
2044                    .map_err(|_| ())
2045            } else {
2046                Err(())
2047            }
2048        }
2049
2050        fn try_get_array_bool(
2051            &self,
2052            column: &impl ColumnRef,
2053        ) -> Result<Option<Vec<Option<bool>>>, ()> {
2054            if let Some(idx) = column.to_index() {
2055                self.try_get::<_, Option<Vec<Option<bool>>>>(idx)
2056                    .map_err(|_| ())
2057            } else if let Some(name) = column.to_name() {
2058                self.try_get::<_, Option<Vec<Option<bool>>>>(name)
2059                    .map_err(|_| ())
2060            } else {
2061                Err(())
2062            }
2063        }
2064
2065        fn try_get_array_i16(
2066            &self,
2067            column: &impl ColumnRef,
2068        ) -> Result<Option<Vec<Option<i16>>>, ()> {
2069            if let Some(idx) = column.to_index() {
2070                self.try_get::<_, Option<Vec<Option<i16>>>>(idx)
2071                    .map_err(|_| ())
2072            } else if let Some(name) = column.to_name() {
2073                self.try_get::<_, Option<Vec<Option<i16>>>>(name)
2074                    .map_err(|_| ())
2075            } else {
2076                Err(())
2077            }
2078        }
2079
2080        fn try_get_array_i32(
2081            &self,
2082            column: &impl ColumnRef,
2083        ) -> Result<Option<Vec<Option<i32>>>, ()> {
2084            if let Some(idx) = column.to_index() {
2085                self.try_get::<_, Option<Vec<Option<i32>>>>(idx)
2086                    .map_err(|_| ())
2087            } else if let Some(name) = column.to_name() {
2088                self.try_get::<_, Option<Vec<Option<i32>>>>(name)
2089                    .map_err(|_| ())
2090            } else {
2091                Err(())
2092            }
2093        }
2094
2095        fn try_get_array_i64(
2096            &self,
2097            column: &impl ColumnRef,
2098        ) -> Result<Option<Vec<Option<i64>>>, ()> {
2099            if let Some(idx) = column.to_index() {
2100                self.try_get::<_, Option<Vec<Option<i64>>>>(idx)
2101                    .map_err(|_| ())
2102            } else if let Some(name) = column.to_name() {
2103                self.try_get::<_, Option<Vec<Option<i64>>>>(name)
2104                    .map_err(|_| ())
2105            } else {
2106                Err(())
2107            }
2108        }
2109
2110        fn try_get_array_f32(
2111            &self,
2112            column: &impl ColumnRef,
2113        ) -> Result<Option<Vec<Option<f32>>>, ()> {
2114            if let Some(idx) = column.to_index() {
2115                self.try_get::<_, Option<Vec<Option<f32>>>>(idx)
2116                    .map_err(|_| ())
2117            } else if let Some(name) = column.to_name() {
2118                self.try_get::<_, Option<Vec<Option<f32>>>>(name)
2119                    .map_err(|_| ())
2120            } else {
2121                Err(())
2122            }
2123        }
2124
2125        fn try_get_array_f64(
2126            &self,
2127            column: &impl ColumnRef,
2128        ) -> Result<Option<Vec<Option<f64>>>, ()> {
2129            if let Some(idx) = column.to_index() {
2130                self.try_get::<_, Option<Vec<Option<f64>>>>(idx)
2131                    .map_err(|_| ())
2132            } else if let Some(name) = column.to_name() {
2133                self.try_get::<_, Option<Vec<Option<f64>>>>(name)
2134                    .map_err(|_| ())
2135            } else {
2136                Err(())
2137            }
2138        }
2139
2140        fn try_get_array_text(
2141            &self,
2142            column: &impl ColumnRef,
2143        ) -> Result<Option<Vec<Option<String>>>, ()> {
2144            if let Some(idx) = column.to_index() {
2145                self.try_get::<_, Option<Vec<Option<String>>>>(idx)
2146                    .map_err(|_| ())
2147            } else if let Some(name) = column.to_name() {
2148                self.try_get::<_, Option<Vec<Option<String>>>>(name)
2149                    .map_err(|_| ())
2150            } else {
2151                Err(())
2152            }
2153        }
2154
2155        fn try_get_array_bytes(
2156            &self,
2157            column: &impl ColumnRef,
2158        ) -> Result<Option<Vec<Option<Vec<u8>>>>, ()> {
2159            if let Some(idx) = column.to_index() {
2160                self.try_get::<_, Option<Vec<Option<Vec<u8>>>>>(idx)
2161                    .map_err(|_| ())
2162            } else if let Some(name) = column.to_name() {
2163                self.try_get::<_, Option<Vec<Option<Vec<u8>>>>>(name)
2164                    .map_err(|_| ())
2165            } else {
2166                Err(())
2167            }
2168        }
2169
2170        #[cfg(feature = "uuid")]
2171        fn try_get_array_uuid(
2172            &self,
2173            column: &impl ColumnRef,
2174        ) -> Result<Option<Vec<Option<uuid::Uuid>>>, ()> {
2175            if let Some(idx) = column.to_index() {
2176                self.try_get::<_, Option<Vec<Option<uuid::Uuid>>>>(idx)
2177                    .map_err(|_| ())
2178            } else if let Some(name) = column.to_name() {
2179                self.try_get::<_, Option<Vec<Option<uuid::Uuid>>>>(name)
2180                    .map_err(|_| ())
2181            } else {
2182                Err(())
2183            }
2184        }
2185
2186        #[cfg(feature = "serde")]
2187        fn try_get_array_json(
2188            &self,
2189            column: &impl ColumnRef,
2190        ) -> Result<Option<Vec<Option<serde_json::Value>>>, ()> {
2191            if let Some(idx) = column.to_index() {
2192                self.try_get::<_, Option<Vec<Option<serde_json::Value>>>>(idx)
2193                    .map_err(|_| ())
2194            } else if let Some(name) = column.to_name() {
2195                self.try_get::<_, Option<Vec<Option<serde_json::Value>>>>(name)
2196                    .map_err(|_| ())
2197            } else {
2198                Err(())
2199            }
2200        }
2201
2202        #[cfg(feature = "chrono")]
2203        fn try_get_array_date(
2204            &self,
2205            column: &impl ColumnRef,
2206        ) -> Result<Option<Vec<Option<chrono::NaiveDate>>>, ()> {
2207            if let Some(idx) = column.to_index() {
2208                self.try_get::<_, Option<Vec<Option<chrono::NaiveDate>>>>(idx)
2209                    .map_err(|_| ())
2210            } else if let Some(name) = column.to_name() {
2211                self.try_get::<_, Option<Vec<Option<chrono::NaiveDate>>>>(name)
2212                    .map_err(|_| ())
2213            } else {
2214                Err(())
2215            }
2216        }
2217
2218        #[cfg(feature = "chrono")]
2219        fn try_get_array_time(
2220            &self,
2221            column: &impl ColumnRef,
2222        ) -> Result<Option<Vec<Option<chrono::NaiveTime>>>, ()> {
2223            if let Some(idx) = column.to_index() {
2224                self.try_get::<_, Option<Vec<Option<chrono::NaiveTime>>>>(idx)
2225                    .map_err(|_| ())
2226            } else if let Some(name) = column.to_name() {
2227                self.try_get::<_, Option<Vec<Option<chrono::NaiveTime>>>>(name)
2228                    .map_err(|_| ())
2229            } else {
2230                Err(())
2231            }
2232        }
2233
2234        #[cfg(feature = "chrono")]
2235        fn try_get_array_timestamp(
2236            &self,
2237            column: &impl ColumnRef,
2238        ) -> Result<Option<Vec<Option<chrono::NaiveDateTime>>>, ()> {
2239            if let Some(idx) = column.to_index() {
2240                self.try_get::<_, Option<Vec<Option<chrono::NaiveDateTime>>>>(idx)
2241                    .map_err(|_| ())
2242            } else if let Some(name) = column.to_name() {
2243                self.try_get::<_, Option<Vec<Option<chrono::NaiveDateTime>>>>(name)
2244                    .map_err(|_| ())
2245            } else {
2246                Err(())
2247            }
2248        }
2249
2250        #[cfg(feature = "chrono")]
2251        fn try_get_array_timestamptz(
2252            &self,
2253            column: &impl ColumnRef,
2254        ) -> Result<Option<Vec<Option<chrono::DateTime<chrono::FixedOffset>>>>, ()> {
2255            if let Some(idx) = column.to_index() {
2256                self.try_get::<_, Option<Vec<Option<chrono::DateTime<chrono::FixedOffset>>>>>(idx)
2257                    .map_err(|_| ())
2258            } else if let Some(name) = column.to_name() {
2259                self.try_get::<_, Option<Vec<Option<chrono::DateTime<chrono::FixedOffset>>>>>(name)
2260                    .map_err(|_| ())
2261            } else {
2262                Err(())
2263            }
2264        }
2265
2266        #[cfg(feature = "cidr")]
2267        fn try_get_array_inet(
2268            &self,
2269            column: &impl ColumnRef,
2270        ) -> Result<Option<Vec<Option<cidr::IpInet>>>, ()> {
2271            if let Some(idx) = column.to_index() {
2272                self.try_get::<_, Option<Vec<Option<cidr::IpInet>>>>(idx)
2273                    .map_err(|_| ())
2274            } else if let Some(name) = column.to_name() {
2275                self.try_get::<_, Option<Vec<Option<cidr::IpInet>>>>(name)
2276                    .map_err(|_| ())
2277            } else {
2278                Err(())
2279            }
2280        }
2281
2282        #[cfg(feature = "cidr")]
2283        fn try_get_array_cidr(
2284            &self,
2285            column: &impl ColumnRef,
2286        ) -> Result<Option<Vec<Option<cidr::IpCidr>>>, ()> {
2287            if let Some(idx) = column.to_index() {
2288                self.try_get::<_, Option<Vec<Option<cidr::IpCidr>>>>(idx)
2289                    .map_err(|_| ())
2290            } else if let Some(name) = column.to_name() {
2291                self.try_get::<_, Option<Vec<Option<cidr::IpCidr>>>>(name)
2292                    .map_err(|_| ())
2293            } else {
2294                Err(())
2295            }
2296        }
2297
2298        #[cfg(feature = "cidr")]
2299        fn try_get_array_macaddr(
2300            &self,
2301            column: &impl ColumnRef,
2302        ) -> Result<Option<Vec<Option<[u8; 6]>>>, ()> {
2303            match self.try_get_array_text(column) {
2304                Ok(Some(values)) => parse_mac_array::<6>(values).map(Some),
2305                Ok(None) => Ok(None),
2306                Err(()) => Err(()),
2307            }
2308        }
2309
2310        #[cfg(feature = "cidr")]
2311        fn try_get_array_macaddr8(
2312            &self,
2313            column: &impl ColumnRef,
2314        ) -> Result<Option<Vec<Option<[u8; 8]>>>, ()> {
2315            match self.try_get_array_text(column) {
2316                Ok(Some(values)) => parse_mac_array::<8>(values).map(Some),
2317                Ok(None) => Ok(None),
2318                Err(()) => Err(()),
2319            }
2320        }
2321
2322        #[cfg(feature = "geo-types")]
2323        fn try_get_array_point(
2324            &self,
2325            column: &impl ColumnRef,
2326        ) -> Result<Option<Vec<Option<geo_types::Point<f64>>>>, ()> {
2327            if let Some(idx) = column.to_index() {
2328                self.try_get::<_, Option<Vec<Option<geo_types::Point<f64>>>>>(idx)
2329                    .map_err(|_| ())
2330            } else if let Some(name) = column.to_name() {
2331                self.try_get::<_, Option<Vec<Option<geo_types::Point<f64>>>>>(name)
2332                    .map_err(|_| ())
2333            } else {
2334                Err(())
2335            }
2336        }
2337
2338        #[cfg(feature = "geo-types")]
2339        fn try_get_array_linestring(
2340            &self,
2341            column: &impl ColumnRef,
2342        ) -> Result<Option<Vec<Option<geo_types::LineString<f64>>>>, ()> {
2343            if let Some(idx) = column.to_index() {
2344                self.try_get::<_, Option<Vec<Option<geo_types::LineString<f64>>>>>(idx)
2345                    .map_err(|_| ())
2346            } else if let Some(name) = column.to_name() {
2347                self.try_get::<_, Option<Vec<Option<geo_types::LineString<f64>>>>>(name)
2348                    .map_err(|_| ())
2349            } else {
2350                Err(())
2351            }
2352        }
2353
2354        #[cfg(feature = "geo-types")]
2355        fn try_get_array_rect(
2356            &self,
2357            column: &impl ColumnRef,
2358        ) -> Result<Option<Vec<Option<geo_types::Rect<f64>>>>, ()> {
2359            if let Some(idx) = column.to_index() {
2360                self.try_get::<_, Option<Vec<Option<geo_types::Rect<f64>>>>>(idx)
2361                    .map_err(|_| ())
2362            } else if let Some(name) = column.to_name() {
2363                self.try_get::<_, Option<Vec<Option<geo_types::Rect<f64>>>>>(name)
2364                    .map_err(|_| ())
2365            } else {
2366                Err(())
2367            }
2368        }
2369
2370        #[cfg(feature = "bit-vec")]
2371        fn try_get_array_bitvec(
2372            &self,
2373            column: &impl ColumnRef,
2374        ) -> Result<Option<Vec<Option<bit_vec::BitVec>>>, ()> {
2375            if let Some(idx) = column.to_index() {
2376                self.try_get::<_, Option<Vec<Option<bit_vec::BitVec>>>>(idx)
2377                    .map_err(|_| ())
2378            } else if let Some(name) = column.to_name() {
2379                self.try_get::<_, Option<Vec<Option<bit_vec::BitVec>>>>(name)
2380                    .map_err(|_| ())
2381            } else {
2382                Err(())
2383            }
2384        }
2385    }
2386
2387    #[cfg(all(feature = "postgres-sync", not(feature = "tokio-postgres")))]
2388    impl DrizzleRow for postgres::Row {
2389        fn get_column<T: FromPostgresValue>(&self, idx: usize) -> Result<T, DrizzleError> {
2390            convert_column(self, idx)
2391        }
2392
2393        fn get_column_by_name<T: FromPostgresValue>(&self, name: &str) -> Result<T, DrizzleError> {
2394            convert_column(self, name)
2395        }
2396    }
2397}
2398
2399// =============================================================================
2400// UUID support (when feature enabled)
2401// =============================================================================
2402
2403#[cfg(feature = "uuid")]
2404impl FromPostgresValue for uuid::Uuid {
2405    fn from_postgres_bool(_value: bool) -> Result<Self, DrizzleError> {
2406        Err(DrizzleError::ConversionError(
2407            "cannot convert bool to UUID".into(),
2408        ))
2409    }
2410
2411    fn from_postgres_i16(_value: i16) -> Result<Self, DrizzleError> {
2412        Err(DrizzleError::ConversionError(
2413            "cannot convert i16 to UUID".into(),
2414        ))
2415    }
2416
2417    fn from_postgres_i32(_value: i32) -> Result<Self, DrizzleError> {
2418        Err(DrizzleError::ConversionError(
2419            "cannot convert i32 to UUID".into(),
2420        ))
2421    }
2422
2423    fn from_postgres_i64(_value: i64) -> Result<Self, DrizzleError> {
2424        Err(DrizzleError::ConversionError(
2425            "cannot convert i64 to UUID".into(),
2426        ))
2427    }
2428
2429    fn from_postgres_f32(_value: f32) -> Result<Self, DrizzleError> {
2430        Err(DrizzleError::ConversionError(
2431            "cannot convert f32 to UUID".into(),
2432        ))
2433    }
2434
2435    fn from_postgres_f64(_value: f64) -> Result<Self, DrizzleError> {
2436        Err(DrizzleError::ConversionError(
2437            "cannot convert f64 to UUID".into(),
2438        ))
2439    }
2440
2441    fn from_postgres_text(value: &str) -> Result<Self, DrizzleError> {
2442        uuid::Uuid::parse_str(value).map_err(|e| {
2443            DrizzleError::ConversionError(format!("invalid UUID string '{}': {}", value, e).into())
2444        })
2445    }
2446
2447    fn from_postgres_bytes(value: &[u8]) -> Result<Self, DrizzleError> {
2448        uuid::Uuid::from_slice(value)
2449            .map_err(|e| DrizzleError::ConversionError(format!("invalid UUID bytes: {}", e).into()))
2450    }
2451
2452    fn from_postgres_uuid(value: uuid::Uuid) -> Result<Self, DrizzleError> {
2453        Ok(value)
2454    }
2455}
2456
2457macro_rules! impl_from_postgres_value_errors {
2458    ($target:expr) => {
2459        fn from_postgres_bool(_value: bool) -> Result<Self, DrizzleError> {
2460            Err(DrizzleError::ConversionError(
2461                format!("cannot convert bool to {}", $target).into(),
2462            ))
2463        }
2464
2465        fn from_postgres_i16(_value: i16) -> Result<Self, DrizzleError> {
2466            Err(DrizzleError::ConversionError(
2467                format!("cannot convert i16 to {}", $target).into(),
2468            ))
2469        }
2470
2471        fn from_postgres_i32(_value: i32) -> Result<Self, DrizzleError> {
2472            Err(DrizzleError::ConversionError(
2473                format!("cannot convert i32 to {}", $target).into(),
2474            ))
2475        }
2476
2477        fn from_postgres_i64(_value: i64) -> Result<Self, DrizzleError> {
2478            Err(DrizzleError::ConversionError(
2479                format!("cannot convert i64 to {}", $target).into(),
2480            ))
2481        }
2482
2483        fn from_postgres_f32(_value: f32) -> Result<Self, DrizzleError> {
2484            Err(DrizzleError::ConversionError(
2485                format!("cannot convert f32 to {}", $target).into(),
2486            ))
2487        }
2488
2489        fn from_postgres_f64(_value: f64) -> Result<Self, DrizzleError> {
2490            Err(DrizzleError::ConversionError(
2491                format!("cannot convert f64 to {}", $target).into(),
2492            ))
2493        }
2494
2495        fn from_postgres_text(_value: &str) -> Result<Self, DrizzleError> {
2496            Err(DrizzleError::ConversionError(
2497                format!("cannot convert text to {}", $target).into(),
2498            ))
2499        }
2500
2501        fn from_postgres_bytes(_value: &[u8]) -> Result<Self, DrizzleError> {
2502            Err(DrizzleError::ConversionError(
2503                format!("cannot convert bytes to {}", $target).into(),
2504            ))
2505        }
2506    };
2507}
2508
2509// =============================================================================
2510// PostgresEnum support
2511// =============================================================================
2512
2513impl<T> FromPostgresValue for T
2514where
2515    T: super::PostgresEnum,
2516{
2517    fn from_postgres_bool(_value: bool) -> Result<Self, DrizzleError> {
2518        Err(DrizzleError::ConversionError(
2519            "cannot convert bool to PostgresEnum".into(),
2520        ))
2521    }
2522
2523    fn from_postgres_i16(_value: i16) -> Result<Self, DrizzleError> {
2524        Err(DrizzleError::ConversionError(
2525            "cannot convert i16 to PostgresEnum".into(),
2526        ))
2527    }
2528
2529    fn from_postgres_i32(_value: i32) -> Result<Self, DrizzleError> {
2530        Err(DrizzleError::ConversionError(
2531            "cannot convert i32 to PostgresEnum".into(),
2532        ))
2533    }
2534
2535    fn from_postgres_i64(_value: i64) -> Result<Self, DrizzleError> {
2536        Err(DrizzleError::ConversionError(
2537            "cannot convert i64 to PostgresEnum".into(),
2538        ))
2539    }
2540
2541    fn from_postgres_f32(_value: f32) -> Result<Self, DrizzleError> {
2542        Err(DrizzleError::ConversionError(
2543            "cannot convert f32 to PostgresEnum".into(),
2544        ))
2545    }
2546
2547    fn from_postgres_f64(_value: f64) -> Result<Self, DrizzleError> {
2548        Err(DrizzleError::ConversionError(
2549            "cannot convert f64 to PostgresEnum".into(),
2550        ))
2551    }
2552
2553    fn from_postgres_text(value: &str) -> Result<Self, DrizzleError> {
2554        T::try_from_str(value)
2555    }
2556
2557    fn from_postgres_bytes(value: &[u8]) -> Result<Self, DrizzleError> {
2558        let s = std::str::from_utf8(value).map_err(|e| {
2559            DrizzleError::ConversionError(format!("invalid UTF-8 for enum: {}", e).into())
2560        })?;
2561        T::try_from_str(s)
2562    }
2563}
2564
2565// =============================================================================
2566// ARRAY support
2567// =============================================================================
2568
2569impl<'a> FromPostgresValue for Vec<PostgresValue<'a>> {
2570    impl_from_postgres_value_errors!("ARRAY");
2571
2572    fn from_postgres_array<'b>(value: Vec<PostgresValue<'b>>) -> Result<Self, DrizzleError> {
2573        let values = value
2574            .into_iter()
2575            .map(OwnedPostgresValue::from)
2576            .map(PostgresValue::from)
2577            .collect();
2578        Ok(values)
2579    }
2580}
2581
2582impl FromPostgresValue for Vec<OwnedPostgresValue> {
2583    impl_from_postgres_value_errors!("ARRAY");
2584
2585    fn from_postgres_array<'a>(value: Vec<PostgresValue<'a>>) -> Result<Self, DrizzleError> {
2586        Ok(value.into_iter().map(OwnedPostgresValue::from).collect())
2587    }
2588}
2589
2590// =============================================================================
2591// JSON support (when feature enabled)
2592// =============================================================================
2593
2594#[cfg(feature = "serde")]
2595impl FromPostgresValue for serde_json::Value {
2596    impl_from_postgres_value_errors!("JSON");
2597
2598    fn from_postgres_json(value: serde_json::Value) -> Result<Self, DrizzleError> {
2599        Ok(value)
2600    }
2601
2602    fn from_postgres_jsonb(value: serde_json::Value) -> Result<Self, DrizzleError> {
2603        Ok(value)
2604    }
2605}
2606
2607// =============================================================================
2608// Chrono support (when feature enabled)
2609// =============================================================================
2610
2611#[cfg(feature = "chrono")]
2612impl FromPostgresValue for chrono::NaiveDate {
2613    impl_from_postgres_value_errors!("NaiveDate");
2614
2615    fn from_postgres_date(value: chrono::NaiveDate) -> Result<Self, DrizzleError> {
2616        Ok(value)
2617    }
2618}
2619
2620#[cfg(feature = "chrono")]
2621impl FromPostgresValue for chrono::NaiveTime {
2622    impl_from_postgres_value_errors!("NaiveTime");
2623
2624    fn from_postgres_time(value: chrono::NaiveTime) -> Result<Self, DrizzleError> {
2625        Ok(value)
2626    }
2627}
2628
2629#[cfg(feature = "chrono")]
2630impl FromPostgresValue for chrono::NaiveDateTime {
2631    impl_from_postgres_value_errors!("NaiveDateTime");
2632
2633    fn from_postgres_timestamp(value: chrono::NaiveDateTime) -> Result<Self, DrizzleError> {
2634        Ok(value)
2635    }
2636}
2637
2638#[cfg(feature = "chrono")]
2639impl FromPostgresValue for chrono::DateTime<chrono::FixedOffset> {
2640    impl_from_postgres_value_errors!("DateTime<FixedOffset>");
2641
2642    fn from_postgres_timestamptz(
2643        value: chrono::DateTime<chrono::FixedOffset>,
2644    ) -> Result<Self, DrizzleError> {
2645        Ok(value)
2646    }
2647}
2648
2649#[cfg(feature = "chrono")]
2650impl FromPostgresValue for chrono::DateTime<chrono::Utc> {
2651    impl_from_postgres_value_errors!("DateTime<Utc>");
2652
2653    fn from_postgres_timestamptz(
2654        value: chrono::DateTime<chrono::FixedOffset>,
2655    ) -> Result<Self, DrizzleError> {
2656        Ok(value.with_timezone(&chrono::Utc))
2657    }
2658}
2659
2660#[cfg(feature = "chrono")]
2661impl FromPostgresValue for chrono::Duration {
2662    impl_from_postgres_value_errors!("Duration");
2663
2664    fn from_postgres_interval(value: chrono::Duration) -> Result<Self, DrizzleError> {
2665        Ok(value)
2666    }
2667}
2668
2669// =============================================================================
2670// Network types (when feature enabled)
2671// =============================================================================
2672
2673#[cfg(feature = "cidr")]
2674impl FromPostgresValue for cidr::IpInet {
2675    impl_from_postgres_value_errors!("IpInet");
2676
2677    fn from_postgres_inet(value: cidr::IpInet) -> Result<Self, DrizzleError> {
2678        Ok(value)
2679    }
2680}
2681
2682#[cfg(feature = "cidr")]
2683impl FromPostgresValue for cidr::IpCidr {
2684    impl_from_postgres_value_errors!("IpCidr");
2685
2686    fn from_postgres_cidr(value: cidr::IpCidr) -> Result<Self, DrizzleError> {
2687        Ok(value)
2688    }
2689}
2690
2691#[cfg(feature = "cidr")]
2692impl FromPostgresValue for [u8; 6] {
2693    impl_from_postgres_value_errors!("MACADDR");
2694
2695    fn from_postgres_macaddr(value: [u8; 6]) -> Result<Self, DrizzleError> {
2696        Ok(value)
2697    }
2698}
2699
2700#[cfg(feature = "cidr")]
2701impl FromPostgresValue for [u8; 8] {
2702    impl_from_postgres_value_errors!("MACADDR8");
2703
2704    fn from_postgres_macaddr8(value: [u8; 8]) -> Result<Self, DrizzleError> {
2705        Ok(value)
2706    }
2707}
2708
2709// =============================================================================
2710// Geometric types (when feature enabled)
2711// =============================================================================
2712
2713#[cfg(feature = "geo-types")]
2714impl FromPostgresValue for geo_types::Point<f64> {
2715    impl_from_postgres_value_errors!("Point");
2716
2717    fn from_postgres_point(value: geo_types::Point<f64>) -> Result<Self, DrizzleError> {
2718        Ok(value)
2719    }
2720}
2721
2722#[cfg(feature = "geo-types")]
2723impl FromPostgresValue for geo_types::LineString<f64> {
2724    impl_from_postgres_value_errors!("LineString");
2725
2726    fn from_postgres_linestring(value: geo_types::LineString<f64>) -> Result<Self, DrizzleError> {
2727        Ok(value)
2728    }
2729}
2730
2731#[cfg(feature = "geo-types")]
2732impl FromPostgresValue for geo_types::Rect<f64> {
2733    impl_from_postgres_value_errors!("Rect");
2734
2735    fn from_postgres_rect(value: geo_types::Rect<f64>) -> Result<Self, DrizzleError> {
2736        Ok(value)
2737    }
2738}
2739
2740// =============================================================================
2741// Bit string types (when feature enabled)
2742// =============================================================================
2743
2744#[cfg(feature = "bit-vec")]
2745impl FromPostgresValue for bit_vec::BitVec {
2746    impl_from_postgres_value_errors!("BitVec");
2747
2748    fn from_postgres_bitvec(value: bit_vec::BitVec) -> Result<Self, DrizzleError> {
2749        Ok(value)
2750    }
2751}
2752
2753// =============================================================================
2754// ArrayVec/ArrayString support (when feature enabled)
2755// =============================================================================
2756
2757#[cfg(feature = "arrayvec")]
2758impl<const N: usize> FromPostgresValue for arrayvec::ArrayString<N> {
2759    fn from_postgres_bool(value: bool) -> Result<Self, DrizzleError> {
2760        let s = value.to_string();
2761        arrayvec::ArrayString::from(&s).map_err(|_| {
2762            DrizzleError::ConversionError(
2763                format!(
2764                    "String length {} exceeds ArrayString capacity {}",
2765                    s.len(),
2766                    N
2767                )
2768                .into(),
2769            )
2770        })
2771    }
2772
2773    fn from_postgres_i16(value: i16) -> Result<Self, DrizzleError> {
2774        let s = value.to_string();
2775        arrayvec::ArrayString::from(&s).map_err(|_| {
2776            DrizzleError::ConversionError(
2777                format!(
2778                    "String length {} exceeds ArrayString capacity {}",
2779                    s.len(),
2780                    N
2781                )
2782                .into(),
2783            )
2784        })
2785    }
2786
2787    fn from_postgres_i32(value: i32) -> Result<Self, DrizzleError> {
2788        let s = value.to_string();
2789        arrayvec::ArrayString::from(&s).map_err(|_| {
2790            DrizzleError::ConversionError(
2791                format!(
2792                    "String length {} exceeds ArrayString capacity {}",
2793                    s.len(),
2794                    N
2795                )
2796                .into(),
2797            )
2798        })
2799    }
2800
2801    fn from_postgres_i64(value: i64) -> Result<Self, DrizzleError> {
2802        let s = value.to_string();
2803        arrayvec::ArrayString::from(&s).map_err(|_| {
2804            DrizzleError::ConversionError(
2805                format!(
2806                    "String length {} exceeds ArrayString capacity {}",
2807                    s.len(),
2808                    N
2809                )
2810                .into(),
2811            )
2812        })
2813    }
2814
2815    fn from_postgres_f32(value: f32) -> Result<Self, DrizzleError> {
2816        let s = value.to_string();
2817        arrayvec::ArrayString::from(&s).map_err(|_| {
2818            DrizzleError::ConversionError(
2819                format!(
2820                    "String length {} exceeds ArrayString capacity {}",
2821                    s.len(),
2822                    N
2823                )
2824                .into(),
2825            )
2826        })
2827    }
2828
2829    fn from_postgres_f64(value: f64) -> Result<Self, DrizzleError> {
2830        let s = value.to_string();
2831        arrayvec::ArrayString::from(&s).map_err(|_| {
2832            DrizzleError::ConversionError(
2833                format!(
2834                    "String length {} exceeds ArrayString capacity {}",
2835                    s.len(),
2836                    N
2837                )
2838                .into(),
2839            )
2840        })
2841    }
2842
2843    fn from_postgres_text(value: &str) -> Result<Self, DrizzleError> {
2844        arrayvec::ArrayString::from(value).map_err(|_| {
2845            DrizzleError::ConversionError(
2846                format!(
2847                    "Text length {} exceeds ArrayString capacity {}",
2848                    value.len(),
2849                    N
2850                )
2851                .into(),
2852            )
2853        })
2854    }
2855
2856    fn from_postgres_bytes(value: &[u8]) -> Result<Self, DrizzleError> {
2857        let s = String::from_utf8(value.to_vec())
2858            .map_err(|e| DrizzleError::ConversionError(format!("invalid UTF-8: {}", e).into()))?;
2859        arrayvec::ArrayString::from(&s).map_err(|_| {
2860            DrizzleError::ConversionError(
2861                format!(
2862                    "String length {} exceeds ArrayString capacity {}",
2863                    s.len(),
2864                    N
2865                )
2866                .into(),
2867            )
2868        })
2869    }
2870}
2871
2872#[cfg(feature = "arrayvec")]
2873impl<const N: usize> FromPostgresValue for arrayvec::ArrayVec<u8, N> {
2874    fn from_postgres_bool(_value: bool) -> Result<Self, DrizzleError> {
2875        Err(DrizzleError::ConversionError(
2876            "cannot convert bool to ArrayVec<u8>, use BYTEA".into(),
2877        ))
2878    }
2879
2880    fn from_postgres_i16(_value: i16) -> Result<Self, DrizzleError> {
2881        Err(DrizzleError::ConversionError(
2882            "cannot convert i16 to ArrayVec<u8>, use BYTEA".into(),
2883        ))
2884    }
2885
2886    fn from_postgres_i32(_value: i32) -> Result<Self, DrizzleError> {
2887        Err(DrizzleError::ConversionError(
2888            "cannot convert i32 to ArrayVec<u8>, use BYTEA".into(),
2889        ))
2890    }
2891
2892    fn from_postgres_i64(_value: i64) -> Result<Self, DrizzleError> {
2893        Err(DrizzleError::ConversionError(
2894            "cannot convert i64 to ArrayVec<u8>, use BYTEA".into(),
2895        ))
2896    }
2897
2898    fn from_postgres_f32(_value: f32) -> Result<Self, DrizzleError> {
2899        Err(DrizzleError::ConversionError(
2900            "cannot convert f32 to ArrayVec<u8>, use BYTEA".into(),
2901        ))
2902    }
2903
2904    fn from_postgres_f64(_value: f64) -> Result<Self, DrizzleError> {
2905        Err(DrizzleError::ConversionError(
2906            "cannot convert f64 to ArrayVec<u8>, use BYTEA".into(),
2907        ))
2908    }
2909
2910    fn from_postgres_text(_value: &str) -> Result<Self, DrizzleError> {
2911        Err(DrizzleError::ConversionError(
2912            "cannot convert TEXT to ArrayVec<u8>, use BYTEA".into(),
2913        ))
2914    }
2915
2916    fn from_postgres_bytes(value: &[u8]) -> Result<Self, DrizzleError> {
2917        arrayvec::ArrayVec::try_from(value).map_err(|_| {
2918            DrizzleError::ConversionError(
2919                format!(
2920                    "Bytes length {} exceeds ArrayVec capacity {}",
2921                    value.len(),
2922                    N
2923                )
2924                .into(),
2925            )
2926        })
2927    }
2928}