Skip to main content

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