Skip to main content

drizzle_postgres/traits/
value.rs

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