drizzle_postgres/
values.rs

1//! PostgreSQL value conversion traits and types
2
3use drizzle_core::{Placeholder, SQL, SQLParam, error::DrizzleError};
4
5mod owned;
6pub use owned::OwnedPostgresValue;
7
8#[cfg(feature = "uuid")]
9use uuid::Uuid;
10
11#[cfg(feature = "chrono")]
12use chrono::{DateTime, Duration, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime, Utc};
13
14#[cfg(feature = "rust_decimal")]
15use rust_decimal::Decimal;
16
17#[cfg(feature = "ipnet")]
18use ipnet::{IpNet, Ipv4Net, Ipv6Net};
19
20#[cfg(feature = "geo-types")]
21use geo_types::{LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon};
22
23#[cfg(feature = "bitvec")]
24use bitvec::prelude::*;
25
26use std::borrow::Cow;
27use std::marker::PhantomData;
28
29use crate::{PostgresEnum, ToPostgresSQL};
30
31//------------------------------------------------------------------------------
32// InsertValue Definition - SQL-based value for inserts
33//------------------------------------------------------------------------------
34
35/// Wrapper for SQL with type information
36#[derive(Debug, Clone)]
37pub struct ValueWrapper<'a, V: SQLParam, T> {
38    pub value: SQL<'a, V>,
39    pub _phantom: PhantomData<T>,
40}
41
42impl<'a, V: SQLParam, T> ValueWrapper<'a, V, T> {
43    pub const fn new<U>(value: SQL<'a, V>) -> ValueWrapper<'a, V, U> {
44        ValueWrapper {
45            value,
46            _phantom: PhantomData,
47        }
48    }
49}
50
51/// Represents a value for INSERT operations that can be omitted, null, or a SQL expression
52#[derive(Debug, Clone, Default)]
53pub enum PostgresInsertValue<'a, V: SQLParam, T> {
54    /// Omit this column from the INSERT (use database default)
55    #[default]
56    Omit,
57    /// Explicitly insert NULL
58    Null,
59    /// Insert a SQL expression (value, placeholder, etc.)
60    Value(ValueWrapper<'a, V, T>),
61}
62
63impl<'a, T> PostgresInsertValue<'a, PostgresValue<'a>, T> {
64    /// Converts this InsertValue to an owned version with 'static lifetime
65    pub fn into_owned(self) -> PostgresInsertValue<'static, PostgresValue<'static>, T> {
66        match self {
67            PostgresInsertValue::Omit => PostgresInsertValue::Omit,
68            PostgresInsertValue::Null => PostgresInsertValue::Null,
69            PostgresInsertValue::Value(wrapper) => {
70                // Convert PostgresValue parameters to owned values
71                if let Some(drizzle_core::SQLChunk::Param(param)) = wrapper.value.chunks.first() {
72                    if let Some(ref postgres_val) = param.value {
73                        let postgres_val = postgres_val.as_ref();
74                        let owned_postgres_val = OwnedPostgresValue::from(postgres_val.clone());
75                        let static_postgres_val = PostgresValue::from(owned_postgres_val);
76                        let static_sql = drizzle_core::SQL::param(static_postgres_val);
77                        PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'static>, T>::new(
78                            static_sql,
79                        ))
80                    } else {
81                        // NULL parameter
82                        let static_sql = drizzle_core::SQL::param(PostgresValue::Null);
83                        PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'static>, T>::new(
84                            static_sql,
85                        ))
86                    }
87                } else {
88                    // Non-parameter chunk, convert to NULL for simplicity
89                    let static_sql = drizzle_core::SQL::param(PostgresValue::Null);
90                    PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'static>, T>::new(
91                        static_sql,
92                    ))
93                }
94            }
95        }
96    }
97}
98
99// Conversion implementations for PostgresValue-based InsertValue
100
101// Generic conversion from any type T to InsertValue (for same type T)
102impl<'a, T> From<T> for PostgresInsertValue<'a, PostgresValue<'a>, T>
103where
104    T: TryInto<PostgresValue<'a>>,
105{
106    fn from(value: T) -> Self {
107        let sql = value
108            .try_into()
109            .map(|v: PostgresValue<'a>| SQL::from(v))
110            .unwrap_or_else(|_| SQL::from(PostgresValue::Null));
111        PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, T>::new(sql))
112    }
113}
114
115// Specific conversion for &str to String InsertValue
116impl<'a> From<&str> for PostgresInsertValue<'a, PostgresValue<'a>, String> {
117    fn from(value: &str) -> Self {
118        let postgres_value = SQL::param(Cow::Owned(PostgresValue::from(value.to_string())));
119        PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, String>::new(
120            postgres_value,
121        ))
122    }
123}
124
125// Placeholder conversion
126impl<'a, T> From<Placeholder> for PostgresInsertValue<'a, PostgresValue<'a>, T> {
127    fn from(placeholder: Placeholder) -> Self {
128        use drizzle_core::{Param, SQLChunk};
129        let chunk = SQLChunk::Param(Param {
130            placeholder,
131            value: None,
132        });
133        PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, T>::new(
134            std::iter::once(chunk).collect(),
135        ))
136    }
137}
138
139// Option conversion
140impl<'a, T> From<Option<T>> for PostgresInsertValue<'a, PostgresValue<'a>, T>
141where
142    T: ToPostgresSQL<'a>,
143{
144    fn from(value: Option<T>) -> Self {
145        match value {
146            Some(v) => {
147                let sql = v.to_sql();
148                PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, T>::new(sql))
149            }
150            None => PostgresInsertValue::Omit,
151        }
152    }
153}
154
155// UUID conversion for String InsertValue (for text columns)
156#[cfg(feature = "uuid")]
157impl<'a> From<Uuid> for PostgresInsertValue<'a, PostgresValue<'a>, String> {
158    fn from(value: Uuid) -> Self {
159        let postgres_value = PostgresValue::Uuid(value);
160        let sql = SQL::param(postgres_value);
161        PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, String>::new(sql))
162    }
163}
164
165#[cfg(feature = "uuid")]
166impl<'a> From<&'a Uuid> for PostgresInsertValue<'a, PostgresValue<'a>, String> {
167    fn from(value: &'a Uuid) -> Self {
168        let postgres_value = PostgresValue::Uuid(*value);
169        let sql = SQL::param(postgres_value);
170        PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, String>::new(sql))
171    }
172}
173
174//------------------------------------------------------------------------------
175// PostgresValue Definition
176//------------------------------------------------------------------------------
177
178/// Represents a PostgreSQL value
179#[derive(Debug, Clone, PartialEq)]
180pub enum PostgresValue<'a> {
181    /// SMALLINT values (16-bit signed integer)
182    Smallint(i16),
183    /// INTEGER values (32-bit signed integer)
184    Integer(i32),
185    /// BIGINT values (64-bit signed integer)
186    Bigint(i64),
187    /// REAL values (32-bit floating point)
188    Real(f32),
189    /// DOUBLE PRECISION values (64-bit floating point)
190    DoublePrecision(f64),
191    /// TEXT, VARCHAR, CHAR values
192    Text(Cow<'a, str>),
193    /// BYTEA values (binary data)
194    Bytea(Cow<'a, [u8]>),
195    /// BOOLEAN values
196    Boolean(bool),
197    /// UUID values
198    #[cfg(feature = "uuid")]
199    Uuid(Uuid),
200    /// JSON/JSONB values
201    #[cfg(feature = "serde")]
202    Json(serde_json::Value),
203    /// Native PostgreSQL ENUM values
204    Enum(Box<dyn PostgresEnum>),
205
206    // Date and time types
207    /// DATE values
208    #[cfg(feature = "chrono")]
209    Date(NaiveDate),
210    /// TIME values
211    #[cfg(feature = "chrono")]
212    Time(NaiveTime),
213    /// TIMESTAMP values (without timezone)
214    #[cfg(feature = "chrono")]
215    Timestamp(NaiveDateTime),
216    /// TIMESTAMPTZ values (with timezone)
217    #[cfg(feature = "chrono")]
218    TimestampTz(DateTime<FixedOffset>),
219    /// INTERVAL values
220    #[cfg(feature = "chrono")]
221    Interval(Duration),
222
223    // Numeric types
224    /// NUMERIC, DECIMAL values (arbitrary precision)
225    #[cfg(feature = "rust_decimal")]
226    Decimal(Decimal),
227
228    // Network address types
229    /// INET values (IPv4 or IPv6 networks)
230    #[cfg(feature = "ipnet")]
231    Inet(IpNet),
232    /// CIDR values (IPv4 or IPv6 networks)
233    #[cfg(feature = "ipnet")]
234    Cidr(IpNet),
235    /// MACADDR values (MAC addresses)
236    #[cfg(feature = "ipnet")]
237    MacAddr([u8; 6]),
238    /// MACADDR8 values (EUI-64 MAC addresses)
239    #[cfg(feature = "ipnet")]
240    MacAddr8([u8; 8]),
241
242    // Geometric types
243    /// POINT values
244    #[cfg(feature = "geo-types")]
245    Point(Point<f64>),
246    /// LINESTRING values
247    #[cfg(feature = "geo-types")]
248    LineString(LineString<f64>),
249    /// POLYGON values
250    #[cfg(feature = "geo-types")]
251    Polygon(Polygon<f64>),
252    /// MULTIPOINT values
253    #[cfg(feature = "geo-types")]
254    MultiPoint(MultiPoint<f64>),
255    /// MULTILINESTRING values
256    #[cfg(feature = "geo-types")]
257    MultiLineString(MultiLineString<f64>),
258    /// MULTIPOLYGON values
259    #[cfg(feature = "geo-types")]
260    MultiPolygon(MultiPolygon<f64>),
261
262    // Bit string types
263    /// BIT, BIT VARYING values
264    #[cfg(feature = "bitvec")]
265    BitVec(BitVec),
266
267    // Array types (using Vec for simplicity)
268    /// Array of any PostgreSQL type
269    Array(Vec<PostgresValue<'a>>),
270
271    /// NULL value
272    Null,
273}
274
275impl<'a> Default for PostgresValue<'a> {
276    fn default() -> Self {
277        PostgresValue::Null
278    }
279}
280
281impl<'a> std::fmt::Display for PostgresValue<'a> {
282    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
283        let value = match self {
284            PostgresValue::Smallint(i) => i.to_string(),
285            PostgresValue::Integer(i) => i.to_string(),
286            PostgresValue::Bigint(i) => i.to_string(),
287            PostgresValue::Real(r) => r.to_string(),
288            PostgresValue::DoublePrecision(r) => r.to_string(),
289            PostgresValue::Text(cow) => cow.to_string(),
290            PostgresValue::Bytea(cow) => format!(
291                "\\x{}",
292                cow.iter().map(|b| format!("{:02x}", b)).collect::<String>()
293            ),
294            PostgresValue::Boolean(b) => b.to_string(),
295            #[cfg(feature = "uuid")]
296            PostgresValue::Uuid(uuid) => uuid.to_string(),
297            #[cfg(feature = "serde")]
298            PostgresValue::Json(json) => json.to_string(),
299            PostgresValue::Enum(enum_val) => enum_val.variant_name().to_string(),
300
301            // Date and time types
302            #[cfg(feature = "chrono")]
303            PostgresValue::Date(date) => date.format("%Y-%m-%d").to_string(),
304            #[cfg(feature = "chrono")]
305            PostgresValue::Time(time) => time.format("%H:%M:%S%.f").to_string(),
306            #[cfg(feature = "chrono")]
307            PostgresValue::Timestamp(ts) => ts.format("%Y-%m-%d %H:%M:%S%.f").to_string(),
308            #[cfg(feature = "chrono")]
309            PostgresValue::TimestampTz(ts) => ts.format("%Y-%m-%d %H:%M:%S%.f %:z").to_string(),
310            #[cfg(feature = "chrono")]
311            PostgresValue::Interval(dur) => format!("{} seconds", dur.num_seconds()),
312
313            // Numeric types
314            #[cfg(feature = "rust_decimal")]
315            PostgresValue::Decimal(dec) => dec.to_string(),
316
317            // Network address types
318            #[cfg(feature = "ipnet")]
319            PostgresValue::Inet(net) => net.to_string(),
320            #[cfg(feature = "ipnet")]
321            PostgresValue::Cidr(net) => net.to_string(),
322            #[cfg(feature = "ipnet")]
323            PostgresValue::MacAddr(mac) => format!(
324                "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
325                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
326            ),
327            #[cfg(feature = "ipnet")]
328            PostgresValue::MacAddr8(mac) => format!(
329                "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
330                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mac[6], mac[7]
331            ),
332
333            // Geometric types
334            #[cfg(feature = "geo-types")]
335            PostgresValue::Point(point) => format!("({},{})", point.x(), point.y()),
336            #[cfg(feature = "geo-types")]
337            PostgresValue::LineString(line) => {
338                let coords: Vec<String> = line
339                    .coords()
340                    .map(|coord| format!("({},{})", coord.x, coord.y))
341                    .collect();
342                format!("[{}]", coords.join(","))
343            }
344            #[cfg(feature = "geo-types")]
345            PostgresValue::Polygon(poly) => format!(
346                "POLYGON({})",
347                poly.exterior()
348                    .coords()
349                    .map(|c| format!("({},{})", c.x, c.y))
350                    .collect::<Vec<_>>()
351                    .join(",")
352            ),
353            #[cfg(feature = "geo-types")]
354            PostgresValue::MultiPoint(mp) => format!(
355                "MULTIPOINT({})",
356                mp.iter()
357                    .map(|p| format!("({},{})", p.x(), p.y()))
358                    .collect::<Vec<_>>()
359                    .join(",")
360            ),
361            #[cfg(feature = "geo-types")]
362            PostgresValue::MultiLineString(mls) => format!(
363                "MULTILINESTRING({})",
364                mls.iter()
365                    .map(|ls| format!(
366                        "[{}]",
367                        ls.coords()
368                            .map(|c| format!("({},{})", c.x, c.y))
369                            .collect::<Vec<_>>()
370                            .join(",")
371                    ))
372                    .collect::<Vec<_>>()
373                    .join(",")
374            ),
375            #[cfg(feature = "geo-types")]
376            PostgresValue::MultiPolygon(mp) => format!(
377                "MULTIPOLYGON({})",
378                mp.iter()
379                    .map(|p| format!(
380                        "POLYGON({})",
381                        p.exterior()
382                            .coords()
383                            .map(|c| format!("({},{})", c.x, c.y))
384                            .collect::<Vec<_>>()
385                            .join(",")
386                    ))
387                    .collect::<Vec<_>>()
388                    .join(",")
389            ),
390
391            // Bit string types
392            #[cfg(feature = "bitvec")]
393            PostgresValue::BitVec(bv) => bv
394                .iter()
395                .map(|b| if *b { '1' } else { '0' })
396                .collect::<String>(),
397
398            // Array types
399            PostgresValue::Array(arr) => {
400                let elements: Vec<String> = arr.iter().map(|v| v.to_string()).collect();
401                format!("{{{}}}", elements.join(","))
402            }
403
404            PostgresValue::Null => String::new(),
405        };
406        write!(f, "{value}")
407    }
408}
409
410impl<'a> From<SQL<'a, PostgresValue<'a>>> for PostgresValue<'a> {
411    fn from(_value: SQL<'a, PostgresValue<'a>>) -> Self {
412        unimplemented!()
413    }
414}
415
416// Implement core traits required by Drizzle
417impl<'a> SQLParam for PostgresValue<'a> {}
418
419impl<'a> From<PostgresValue<'a>> for SQL<'a, PostgresValue<'a>> {
420    fn from(value: PostgresValue<'a>) -> Self {
421        SQL::param(value)
422    }
423}
424
425//------------------------------------------------------------------------------
426// From<T> implementations
427//------------------------------------------------------------------------------
428
429// --- Integer Types ---
430
431// i8 → SMALLINT (PostgreSQL doesn't have a native i8 type)
432impl<'a> From<i8> for PostgresValue<'a> {
433    fn from(value: i8) -> Self {
434        PostgresValue::Smallint(value as i16)
435    }
436}
437
438impl<'a> From<&'a i8> for PostgresValue<'a> {
439    fn from(value: &'a i8) -> Self {
440        PostgresValue::Smallint(*value as i16)
441    }
442}
443
444// i16 (SMALLINT)
445impl<'a> From<i16> for PostgresValue<'a> {
446    fn from(value: i16) -> Self {
447        PostgresValue::Smallint(value)
448    }
449}
450
451impl<'a> From<&'a i16> for PostgresValue<'a> {
452    fn from(value: &'a i16) -> Self {
453        PostgresValue::Smallint(*value)
454    }
455}
456
457// i32 (INTEGER)
458impl<'a> From<i32> for PostgresValue<'a> {
459    fn from(value: i32) -> Self {
460        PostgresValue::Integer(value)
461    }
462}
463
464impl<'a> From<&'a i32> for PostgresValue<'a> {
465    fn from(value: &'a i32) -> Self {
466        PostgresValue::Integer(*value)
467    }
468}
469
470// i64 (BIGINT)
471impl<'a> From<i64> for PostgresValue<'a> {
472    fn from(value: i64) -> Self {
473        PostgresValue::Bigint(value)
474    }
475}
476
477impl<'a> From<&'a i64> for PostgresValue<'a> {
478    fn from(value: &'a i64) -> Self {
479        PostgresValue::Bigint(*value)
480    }
481}
482
483// u8 → SMALLINT (PostgreSQL doesn't have unsigned types)
484impl<'a> From<u8> for PostgresValue<'a> {
485    fn from(value: u8) -> Self {
486        PostgresValue::Smallint(value as i16)
487    }
488}
489
490impl<'a> From<&'a u8> for PostgresValue<'a> {
491    fn from(value: &'a u8) -> Self {
492        PostgresValue::Smallint(*value as i16)
493    }
494}
495
496// u16 → INTEGER (cast to larger signed type)
497impl<'a> From<u16> for PostgresValue<'a> {
498    fn from(value: u16) -> Self {
499        PostgresValue::Integer(value as i32)
500    }
501}
502
503impl<'a> From<&'a u16> for PostgresValue<'a> {
504    fn from(value: &'a u16) -> Self {
505        PostgresValue::Integer(*value as i32)
506    }
507}
508
509// u32 → BIGINT (cast to larger signed type since u32 max > i32 max)
510impl<'a> From<u32> for PostgresValue<'a> {
511    fn from(value: u32) -> Self {
512        PostgresValue::Bigint(value as i64)
513    }
514}
515
516impl<'a> From<&'a u32> for PostgresValue<'a> {
517    fn from(value: &'a u32) -> Self {
518        PostgresValue::Bigint(*value as i64)
519    }
520}
521
522// u64 → BIGINT (cast with potential overflow since u64 max > i64 max)
523impl<'a> From<u64> for PostgresValue<'a> {
524    fn from(value: u64) -> Self {
525        PostgresValue::Bigint(value as i64)
526    }
527}
528
529impl<'a> From<&'a u64> for PostgresValue<'a> {
530    fn from(value: &'a u64) -> Self {
531        PostgresValue::Bigint(*value as i64)
532    }
533}
534
535// isize → BIGINT (platform-dependent size)
536impl<'a> From<isize> for PostgresValue<'a> {
537    fn from(value: isize) -> Self {
538        PostgresValue::Bigint(value as i64)
539    }
540}
541
542impl<'a> From<&'a isize> for PostgresValue<'a> {
543    fn from(value: &'a isize) -> Self {
544        PostgresValue::Bigint(*value as i64)
545    }
546}
547
548// usize → BIGINT (platform-dependent size)
549impl<'a> From<usize> for PostgresValue<'a> {
550    fn from(value: usize) -> Self {
551        PostgresValue::Bigint(value as i64)
552    }
553}
554
555impl<'a> From<&'a usize> for PostgresValue<'a> {
556    fn from(value: &'a usize) -> Self {
557        PostgresValue::Bigint(*value as i64)
558    }
559}
560
561// --- Floating Point Types ---
562
563// f32 (REAL)
564impl<'a> From<f32> for PostgresValue<'a> {
565    fn from(value: f32) -> Self {
566        PostgresValue::Real(value)
567    }
568}
569
570impl<'a> From<&'a f32> for PostgresValue<'a> {
571    fn from(value: &'a f32) -> Self {
572        PostgresValue::Real(*value)
573    }
574}
575
576// f64 (DOUBLE PRECISION)
577impl<'a> From<f64> for PostgresValue<'a> {
578    fn from(value: f64) -> Self {
579        PostgresValue::DoublePrecision(value)
580    }
581}
582
583impl<'a> From<&'a f64> for PostgresValue<'a> {
584    fn from(value: &'a f64) -> Self {
585        PostgresValue::DoublePrecision(*value)
586    }
587}
588
589// --- Boolean ---
590
591impl<'a> From<bool> for PostgresValue<'a> {
592    fn from(value: bool) -> Self {
593        PostgresValue::Boolean(value)
594    }
595}
596
597impl<'a> From<&'a bool> for PostgresValue<'a> {
598    fn from(value: &'a bool) -> Self {
599        PostgresValue::Boolean(*value)
600    }
601}
602
603// --- String Types ---
604
605impl<'a> From<&'a str> for PostgresValue<'a> {
606    fn from(value: &'a str) -> Self {
607        PostgresValue::Text(Cow::Borrowed(value))
608    }
609}
610
611impl<'a> From<String> for PostgresValue<'a> {
612    fn from(value: String) -> Self {
613        PostgresValue::Text(Cow::Owned(value))
614    }
615}
616
617impl<'a> From<&'a String> for PostgresValue<'a> {
618    fn from(value: &'a String) -> Self {
619        PostgresValue::Text(Cow::Borrowed(value))
620    }
621}
622
623// --- Binary Data ---
624
625impl<'a> From<&'a [u8]> for PostgresValue<'a> {
626    fn from(value: &'a [u8]) -> Self {
627        PostgresValue::Bytea(Cow::Borrowed(value))
628    }
629}
630
631impl<'a> From<Vec<u8>> for PostgresValue<'a> {
632    fn from(value: Vec<u8>) -> Self {
633        PostgresValue::Bytea(Cow::Owned(value))
634    }
635}
636
637// --- UUID ---
638
639#[cfg(feature = "uuid")]
640impl<'a> From<Uuid> for PostgresValue<'a> {
641    fn from(value: Uuid) -> Self {
642        PostgresValue::Uuid(value)
643    }
644}
645
646#[cfg(feature = "uuid")]
647impl<'a> From<&'a Uuid> for PostgresValue<'a> {
648    fn from(value: &'a Uuid) -> Self {
649        PostgresValue::Uuid(*value)
650    }
651}
652
653// --- JSON ---
654
655#[cfg(feature = "serde")]
656impl<'a> From<serde_json::Value> for PostgresValue<'a> {
657    fn from(value: serde_json::Value) -> Self {
658        PostgresValue::Json(value)
659    }
660}
661
662#[cfg(feature = "serde")]
663impl<'a> From<&'a serde_json::Value> for PostgresValue<'a> {
664    fn from(value: &'a serde_json::Value) -> Self {
665        PostgresValue::Json(value.clone())
666    }
667}
668
669// --- Date/Time Types ---
670
671#[cfg(feature = "chrono")]
672impl<'a> From<NaiveDate> for PostgresValue<'a> {
673    fn from(value: NaiveDate) -> Self {
674        PostgresValue::Date(value)
675    }
676}
677
678#[cfg(feature = "chrono")]
679impl<'a> From<&'a NaiveDate> for PostgresValue<'a> {
680    fn from(value: &'a NaiveDate) -> Self {
681        PostgresValue::Date(*value)
682    }
683}
684
685#[cfg(feature = "chrono")]
686impl<'a> From<NaiveTime> for PostgresValue<'a> {
687    fn from(value: NaiveTime) -> Self {
688        PostgresValue::Time(value)
689    }
690}
691
692#[cfg(feature = "chrono")]
693impl<'a> From<&'a NaiveTime> for PostgresValue<'a> {
694    fn from(value: &'a NaiveTime) -> Self {
695        PostgresValue::Time(*value)
696    }
697}
698
699#[cfg(feature = "chrono")]
700impl<'a> From<NaiveDateTime> for PostgresValue<'a> {
701    fn from(value: NaiveDateTime) -> Self {
702        PostgresValue::Timestamp(value)
703    }
704}
705
706#[cfg(feature = "chrono")]
707impl<'a> From<&'a NaiveDateTime> for PostgresValue<'a> {
708    fn from(value: &'a NaiveDateTime) -> Self {
709        PostgresValue::Timestamp(*value)
710    }
711}
712
713#[cfg(feature = "chrono")]
714impl<'a> From<DateTime<FixedOffset>> for PostgresValue<'a> {
715    fn from(value: DateTime<FixedOffset>) -> Self {
716        PostgresValue::TimestampTz(value)
717    }
718}
719
720#[cfg(feature = "chrono")]
721impl<'a> From<&'a DateTime<FixedOffset>> for PostgresValue<'a> {
722    fn from(value: &'a DateTime<FixedOffset>) -> Self {
723        PostgresValue::TimestampTz(*value)
724    }
725}
726
727#[cfg(feature = "chrono")]
728impl<'a> From<DateTime<Utc>> for PostgresValue<'a> {
729    fn from(value: DateTime<Utc>) -> Self {
730        PostgresValue::TimestampTz(value.into())
731    }
732}
733
734#[cfg(feature = "chrono")]
735impl<'a> From<&'a DateTime<Utc>> for PostgresValue<'a> {
736    fn from(value: &'a DateTime<Utc>) -> Self {
737        PostgresValue::TimestampTz((*value).into())
738    }
739}
740
741#[cfg(feature = "chrono")]
742impl<'a> From<Duration> for PostgresValue<'a> {
743    fn from(value: Duration) -> Self {
744        PostgresValue::Interval(value)
745    }
746}
747
748#[cfg(feature = "chrono")]
749impl<'a> From<&'a Duration> for PostgresValue<'a> {
750    fn from(value: &'a Duration) -> Self {
751        PostgresValue::Interval(*value)
752    }
753}
754
755// --- Numeric Types ---
756
757#[cfg(feature = "rust_decimal")]
758impl<'a> From<Decimal> for PostgresValue<'a> {
759    fn from(value: Decimal) -> Self {
760        PostgresValue::Decimal(value)
761    }
762}
763
764#[cfg(feature = "rust_decimal")]
765impl<'a> From<&'a Decimal> for PostgresValue<'a> {
766    fn from(value: &'a Decimal) -> Self {
767        PostgresValue::Decimal(*value)
768    }
769}
770
771// --- Network Address Types ---
772
773#[cfg(feature = "ipnet")]
774impl<'a> From<IpNet> for PostgresValue<'a> {
775    fn from(value: IpNet) -> Self {
776        PostgresValue::Inet(value)
777    }
778}
779
780#[cfg(feature = "ipnet")]
781impl<'a> From<&'a IpNet> for PostgresValue<'a> {
782    fn from(value: &'a IpNet) -> Self {
783        PostgresValue::Inet(*value)
784    }
785}
786
787#[cfg(feature = "ipnet")]
788impl<'a> From<Ipv4Net> for PostgresValue<'a> {
789    fn from(value: Ipv4Net) -> Self {
790        PostgresValue::Inet(value.into())
791    }
792}
793
794#[cfg(feature = "ipnet")]
795impl<'a> From<Ipv6Net> for PostgresValue<'a> {
796    fn from(value: Ipv6Net) -> Self {
797        PostgresValue::Inet(value.into())
798    }
799}
800
801#[cfg(feature = "ipnet")]
802impl<'a> From<[u8; 6]> for PostgresValue<'a> {
803    fn from(value: [u8; 6]) -> Self {
804        PostgresValue::MacAddr(value)
805    }
806}
807
808#[cfg(feature = "ipnet")]
809impl<'a> From<&'a [u8; 6]> for PostgresValue<'a> {
810    fn from(value: &'a [u8; 6]) -> Self {
811        PostgresValue::MacAddr(*value)
812    }
813}
814
815#[cfg(feature = "ipnet")]
816impl<'a> From<[u8; 8]> for PostgresValue<'a> {
817    fn from(value: [u8; 8]) -> Self {
818        PostgresValue::MacAddr8(value)
819    }
820}
821
822#[cfg(feature = "ipnet")]
823impl<'a> From<&'a [u8; 8]> for PostgresValue<'a> {
824    fn from(value: &'a [u8; 8]) -> Self {
825        PostgresValue::MacAddr8(*value)
826    }
827}
828
829// --- Geometric Types ---
830
831#[cfg(feature = "geo-types")]
832impl<'a> From<Point<f64>> for PostgresValue<'a> {
833    fn from(value: Point<f64>) -> Self {
834        PostgresValue::Point(value)
835    }
836}
837
838#[cfg(feature = "geo-types")]
839impl<'a> From<&'a Point<f64>> for PostgresValue<'a> {
840    fn from(value: &'a Point<f64>) -> Self {
841        PostgresValue::Point(*value)
842    }
843}
844
845#[cfg(feature = "geo-types")]
846impl<'a> From<LineString<f64>> for PostgresValue<'a> {
847    fn from(value: LineString<f64>) -> Self {
848        PostgresValue::LineString(value)
849    }
850}
851
852#[cfg(feature = "geo-types")]
853impl<'a> From<&'a LineString<f64>> for PostgresValue<'a> {
854    fn from(value: &'a LineString<f64>) -> Self {
855        PostgresValue::LineString(value.clone())
856    }
857}
858
859#[cfg(feature = "geo-types")]
860impl<'a> From<Polygon<f64>> for PostgresValue<'a> {
861    fn from(value: Polygon<f64>) -> Self {
862        PostgresValue::Polygon(value)
863    }
864}
865
866#[cfg(feature = "geo-types")]
867impl<'a> From<&'a Polygon<f64>> for PostgresValue<'a> {
868    fn from(value: &'a Polygon<f64>) -> Self {
869        PostgresValue::Polygon(value.clone())
870    }
871}
872
873#[cfg(feature = "geo-types")]
874impl<'a> From<MultiPoint<f64>> for PostgresValue<'a> {
875    fn from(value: MultiPoint<f64>) -> Self {
876        PostgresValue::MultiPoint(value)
877    }
878}
879
880#[cfg(feature = "geo-types")]
881impl<'a> From<&'a MultiPoint<f64>> for PostgresValue<'a> {
882    fn from(value: &'a MultiPoint<f64>) -> Self {
883        PostgresValue::MultiPoint(value.clone())
884    }
885}
886
887#[cfg(feature = "geo-types")]
888impl<'a> From<MultiLineString<f64>> for PostgresValue<'a> {
889    fn from(value: MultiLineString<f64>) -> Self {
890        PostgresValue::MultiLineString(value)
891    }
892}
893
894#[cfg(feature = "geo-types")]
895impl<'a> From<&'a MultiLineString<f64>> for PostgresValue<'a> {
896    fn from(value: &'a MultiLineString<f64>) -> Self {
897        PostgresValue::MultiLineString(value.clone())
898    }
899}
900
901#[cfg(feature = "geo-types")]
902impl<'a> From<MultiPolygon<f64>> for PostgresValue<'a> {
903    fn from(value: MultiPolygon<f64>) -> Self {
904        PostgresValue::MultiPolygon(value)
905    }
906}
907
908#[cfg(feature = "geo-types")]
909impl<'a> From<&'a MultiPolygon<f64>> for PostgresValue<'a> {
910    fn from(value: &'a MultiPolygon<f64>) -> Self {
911        PostgresValue::MultiPolygon(value.clone())
912    }
913}
914
915// --- Bit String Types ---
916
917#[cfg(feature = "bitvec")]
918impl<'a> From<BitVec> for PostgresValue<'a> {
919    fn from(value: BitVec) -> Self {
920        PostgresValue::BitVec(value)
921    }
922}
923
924#[cfg(feature = "bitvec")]
925impl<'a> From<&'a BitVec> for PostgresValue<'a> {
926    fn from(value: &'a BitVec) -> Self {
927        PostgresValue::BitVec(value.clone())
928    }
929}
930
931// --- Array Types ---
932
933impl<'a> From<Vec<PostgresValue<'a>>> for PostgresValue<'a> {
934    fn from(value: Vec<PostgresValue<'a>>) -> Self {
935        PostgresValue::Array(value)
936    }
937}
938
939impl<'a> From<&'a [PostgresValue<'a>]> for PostgresValue<'a> {
940    fn from(value: &'a [PostgresValue<'a>]) -> Self {
941        PostgresValue::Array(value.to_vec())
942    }
943}
944
945// --- Option Types ---
946impl<'a, T> From<Option<T>> for PostgresValue<'a>
947where
948    T: TryInto<PostgresValue<'a>>,
949{
950    fn from(value: Option<T>) -> Self {
951        match value {
952            Some(value) => value.try_into().unwrap_or(PostgresValue::Null),
953            None => PostgresValue::Null,
954        }
955    }
956}
957
958// --- Cow integration for SQL struct ---
959impl<'a> From<PostgresValue<'a>> for Cow<'a, PostgresValue<'a>> {
960    fn from(value: PostgresValue<'a>) -> Self {
961        Cow::Owned(value)
962    }
963}
964
965impl<'a> From<&'a PostgresValue<'a>> for Cow<'a, PostgresValue<'a>> {
966    fn from(value: &'a PostgresValue<'a>) -> Self {
967        Cow::Borrowed(value)
968    }
969}
970
971//------------------------------------------------------------------------------
972// TryFrom<PostgresValue> implementations
973//------------------------------------------------------------------------------
974
975// --- Integer Types ---
976
977impl<'a> TryFrom<PostgresValue<'a>> for i16 {
978    type Error = DrizzleError;
979
980    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
981        match value {
982            PostgresValue::Smallint(i) => Ok(i),
983            PostgresValue::Integer(i) => Ok(i.try_into()?),
984            PostgresValue::Bigint(i) => Ok(i.try_into()?),
985            _ => Err(DrizzleError::ConversionError(
986                format!("Cannot convert {:?} to i16", value).into(),
987            )),
988        }
989    }
990}
991
992impl<'a> TryFrom<PostgresValue<'a>> for i32 {
993    type Error = DrizzleError;
994
995    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
996        match value {
997            PostgresValue::Smallint(i) => Ok(i.into()),
998            PostgresValue::Integer(i) => Ok(i),
999            PostgresValue::Bigint(i) => Ok(i.try_into()?),
1000            _ => Err(DrizzleError::ConversionError(
1001                format!("Cannot convert {:?} to i32", value).into(),
1002            )),
1003        }
1004    }
1005}
1006
1007impl<'a> TryFrom<PostgresValue<'a>> for i64 {
1008    type Error = DrizzleError;
1009
1010    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1011        match value {
1012            PostgresValue::Smallint(i) => Ok(i.into()),
1013            PostgresValue::Integer(i) => Ok(i.into()),
1014            PostgresValue::Bigint(i) => Ok(i),
1015            _ => Err(DrizzleError::ConversionError(
1016                format!("Cannot convert {:?} to i64", value).into(),
1017            )),
1018        }
1019    }
1020}
1021
1022// --- Floating Point Types ---
1023
1024impl<'a> TryFrom<PostgresValue<'a>> for f32 {
1025    type Error = DrizzleError;
1026
1027    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1028        match value {
1029            PostgresValue::Real(f) => Ok(f),
1030            PostgresValue::DoublePrecision(f) => Ok(f as f32),
1031            PostgresValue::Smallint(i) => Ok(i as f32),
1032            PostgresValue::Integer(i) => Ok(i as f32),
1033            PostgresValue::Bigint(i) => Ok(i as f32),
1034            _ => Err(DrizzleError::ConversionError(
1035                format!("Cannot convert {:?} to f32", value).into(),
1036            )),
1037        }
1038    }
1039}
1040
1041impl<'a> TryFrom<PostgresValue<'a>> for f64 {
1042    type Error = DrizzleError;
1043
1044    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1045        match value {
1046            PostgresValue::Real(f) => Ok(f as f64),
1047            PostgresValue::DoublePrecision(f) => Ok(f),
1048            PostgresValue::Smallint(i) => Ok(i as f64),
1049            PostgresValue::Integer(i) => Ok(i as f64),
1050            PostgresValue::Bigint(i) => Ok(i as f64),
1051            _ => Err(DrizzleError::ConversionError(
1052                format!("Cannot convert {:?} to f64", value).into(),
1053            )),
1054        }
1055    }
1056}
1057
1058// --- Boolean ---
1059
1060impl<'a> TryFrom<PostgresValue<'a>> for bool {
1061    type Error = DrizzleError;
1062
1063    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1064        match value {
1065            PostgresValue::Boolean(b) => Ok(b),
1066            _ => Err(DrizzleError::ConversionError(
1067                format!("Cannot convert {:?} to bool", value).into(),
1068            )),
1069        }
1070    }
1071}
1072
1073// --- String Types ---
1074
1075impl<'a> TryFrom<PostgresValue<'a>> for String {
1076    type Error = DrizzleError;
1077
1078    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1079        match value {
1080            PostgresValue::Text(cow) => Ok(cow.into_owned()),
1081            _ => Err(DrizzleError::ConversionError(
1082                format!("Cannot convert {:?} to String", value).into(),
1083            )),
1084        }
1085    }
1086}
1087
1088// --- Binary Data ---
1089
1090impl<'a> TryFrom<PostgresValue<'a>> for Vec<u8> {
1091    type Error = DrizzleError;
1092
1093    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1094        match value {
1095            PostgresValue::Bytea(cow) => Ok(cow.into_owned()),
1096            _ => Err(DrizzleError::ConversionError(
1097                format!("Cannot convert {:?} to Vec<u8>", value).into(),
1098            )),
1099        }
1100    }
1101}
1102
1103// --- UUID ---
1104
1105#[cfg(feature = "uuid")]
1106impl<'a> TryFrom<PostgresValue<'a>> for Uuid {
1107    type Error = DrizzleError;
1108
1109    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1110        match value {
1111            PostgresValue::Uuid(uuid) => Ok(uuid),
1112            PostgresValue::Text(cow) => Ok(Uuid::parse_str(cow.as_ref())?),
1113            _ => Err(DrizzleError::ConversionError(
1114                format!("Cannot convert {:?} to UUID", value).into(),
1115            )),
1116        }
1117    }
1118}
1119
1120// --- JSON ---
1121
1122#[cfg(feature = "serde")]
1123impl<'a> TryFrom<PostgresValue<'a>> for serde_json::Value {
1124    type Error = DrizzleError;
1125
1126    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1127        match value {
1128            PostgresValue::Json(json) => Ok(json),
1129            PostgresValue::Text(cow) => serde_json::from_str(cow.as_ref()).map_err(|e| {
1130                DrizzleError::ConversionError(format!("Failed to parse JSON: {}", e).into())
1131            }),
1132            _ => Err(DrizzleError::ConversionError(
1133                format!("Cannot convert {:?} to JSON", value).into(),
1134            )),
1135        }
1136    }
1137}
1138
1139// --- Date/Time TryFrom implementations ---
1140
1141#[cfg(feature = "chrono")]
1142impl<'a> TryFrom<PostgresValue<'a>> for NaiveDate {
1143    type Error = DrizzleError;
1144
1145    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1146        match value {
1147            PostgresValue::Date(date) => Ok(date),
1148            PostgresValue::Timestamp(ts) => Ok(ts.date()),
1149            PostgresValue::TimestampTz(ts) => Ok(ts.date_naive()),
1150            _ => Err(DrizzleError::ConversionError(
1151                format!("Cannot convert {:?} to NaiveDate", value).into(),
1152            )),
1153        }
1154    }
1155}
1156
1157#[cfg(feature = "chrono")]
1158impl<'a> TryFrom<PostgresValue<'a>> for NaiveTime {
1159    type Error = DrizzleError;
1160
1161    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1162        match value {
1163            PostgresValue::Time(time) => Ok(time),
1164            PostgresValue::Timestamp(ts) => Ok(ts.time()),
1165            PostgresValue::TimestampTz(ts) => Ok(ts.time()),
1166            _ => Err(DrizzleError::ConversionError(
1167                format!("Cannot convert {:?} to NaiveTime", value).into(),
1168            )),
1169        }
1170    }
1171}
1172
1173#[cfg(feature = "chrono")]
1174impl<'a> TryFrom<PostgresValue<'a>> for NaiveDateTime {
1175    type Error = DrizzleError;
1176
1177    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1178        match value {
1179            PostgresValue::Timestamp(ts) => Ok(ts),
1180            PostgresValue::TimestampTz(ts) => Ok(ts.naive_utc()),
1181            _ => Err(DrizzleError::ConversionError(
1182                format!("Cannot convert {:?} to NaiveDateTime", value).into(),
1183            )),
1184        }
1185    }
1186}
1187
1188#[cfg(feature = "chrono")]
1189impl<'a> TryFrom<PostgresValue<'a>> for DateTime<FixedOffset> {
1190    type Error = DrizzleError;
1191
1192    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1193        match value {
1194            PostgresValue::TimestampTz(ts) => Ok(ts),
1195            _ => Err(DrizzleError::ConversionError(
1196                format!("Cannot convert {:?} to DateTime<FixedOffset>", value).into(),
1197            )),
1198        }
1199    }
1200}
1201
1202#[cfg(feature = "chrono")]
1203impl<'a> TryFrom<PostgresValue<'a>> for DateTime<Utc> {
1204    type Error = DrizzleError;
1205
1206    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1207        match value {
1208            PostgresValue::TimestampTz(ts) => Ok(ts.with_timezone(&Utc)),
1209            _ => Err(DrizzleError::ConversionError(
1210                format!("Cannot convert {:?} to DateTime<Utc>", value).into(),
1211            )),
1212        }
1213    }
1214}
1215
1216#[cfg(feature = "chrono")]
1217impl<'a> TryFrom<PostgresValue<'a>> for Duration {
1218    type Error = DrizzleError;
1219
1220    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1221        match value {
1222            PostgresValue::Interval(duration) => Ok(duration),
1223            _ => Err(DrizzleError::ConversionError(
1224                format!("Cannot convert {:?} to Duration", value).into(),
1225            )),
1226        }
1227    }
1228}
1229
1230// --- Numeric TryFrom implementations ---
1231
1232#[cfg(feature = "rust_decimal")]
1233impl<'a> TryFrom<PostgresValue<'a>> for Decimal {
1234    type Error = DrizzleError;
1235
1236    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1237        match value {
1238            PostgresValue::Decimal(dec) => Ok(dec),
1239            PostgresValue::Smallint(i) => Ok(Decimal::from(i)),
1240            PostgresValue::Integer(i) => Ok(Decimal::from(i)),
1241            PostgresValue::Bigint(i) => Ok(Decimal::from(i)),
1242            PostgresValue::Real(f) => Decimal::try_from(f).map_err(|e| {
1243                DrizzleError::ConversionError(
1244                    format!("Failed to convert float to decimal: {}", e).into(),
1245                )
1246            }),
1247            PostgresValue::DoublePrecision(f) => Decimal::try_from(f).map_err(|e| {
1248                DrizzleError::ConversionError(
1249                    format!("Failed to convert float to decimal: {}", e).into(),
1250                )
1251            }),
1252            _ => Err(DrizzleError::ConversionError(
1253                format!("Cannot convert {:?} to Decimal", value).into(),
1254            )),
1255        }
1256    }
1257}
1258
1259// --- Network Address TryFrom implementations ---
1260
1261#[cfg(feature = "ipnet")]
1262impl<'a> TryFrom<PostgresValue<'a>> for IpNet {
1263    type Error = DrizzleError;
1264
1265    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1266        match value {
1267            PostgresValue::Inet(net) => Ok(net),
1268            PostgresValue::Cidr(net) => Ok(net),
1269            _ => Err(DrizzleError::ConversionError(
1270                format!("Cannot convert {:?} to IpNet", value).into(),
1271            )),
1272        }
1273    }
1274}
1275
1276#[cfg(feature = "ipnet")]
1277impl<'a> TryFrom<PostgresValue<'a>> for [u8; 6] {
1278    type Error = DrizzleError;
1279
1280    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1281        match value {
1282            PostgresValue::MacAddr(mac) => Ok(mac),
1283            _ => Err(DrizzleError::ConversionError(
1284                format!("Cannot convert {:?} to [u8; 6]", value).into(),
1285            )),
1286        }
1287    }
1288}
1289
1290#[cfg(feature = "ipnet")]
1291impl<'a> TryFrom<PostgresValue<'a>> for [u8; 8] {
1292    type Error = DrizzleError;
1293
1294    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1295        match value {
1296            PostgresValue::MacAddr8(mac) => Ok(mac),
1297            _ => Err(DrizzleError::ConversionError(
1298                format!("Cannot convert {:?} to [u8; 8]", value).into(),
1299            )),
1300        }
1301    }
1302}
1303
1304// --- Geometric TryFrom implementations ---
1305
1306#[cfg(feature = "geo-types")]
1307impl<'a> TryFrom<PostgresValue<'a>> for Point<f64> {
1308    type Error = DrizzleError;
1309
1310    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1311        match value {
1312            PostgresValue::Point(point) => Ok(point),
1313            _ => Err(DrizzleError::ConversionError(
1314                format!("Cannot convert {:?} to Point", value).into(),
1315            )),
1316        }
1317    }
1318}
1319
1320#[cfg(feature = "geo-types")]
1321impl<'a> TryFrom<PostgresValue<'a>> for LineString<f64> {
1322    type Error = DrizzleError;
1323
1324    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1325        match value {
1326            PostgresValue::LineString(line) => Ok(line),
1327            _ => Err(DrizzleError::ConversionError(
1328                format!("Cannot convert {:?} to LineString", value).into(),
1329            )),
1330        }
1331    }
1332}
1333
1334#[cfg(feature = "geo-types")]
1335impl<'a> TryFrom<PostgresValue<'a>> for Polygon<f64> {
1336    type Error = DrizzleError;
1337
1338    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1339        match value {
1340            PostgresValue::Polygon(poly) => Ok(poly),
1341            _ => Err(DrizzleError::ConversionError(
1342                format!("Cannot convert {:?} to Polygon", value).into(),
1343            )),
1344        }
1345    }
1346}
1347
1348#[cfg(feature = "geo-types")]
1349impl<'a> TryFrom<PostgresValue<'a>> for MultiPoint<f64> {
1350    type Error = DrizzleError;
1351
1352    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1353        match value {
1354            PostgresValue::MultiPoint(mp) => Ok(mp),
1355            _ => Err(DrizzleError::ConversionError(
1356                format!("Cannot convert {:?} to MultiPoint", value).into(),
1357            )),
1358        }
1359    }
1360}
1361
1362#[cfg(feature = "geo-types")]
1363impl<'a> TryFrom<PostgresValue<'a>> for MultiLineString<f64> {
1364    type Error = DrizzleError;
1365
1366    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1367        match value {
1368            PostgresValue::MultiLineString(mls) => Ok(mls),
1369            _ => Err(DrizzleError::ConversionError(
1370                format!("Cannot convert {:?} to MultiLineString", value).into(),
1371            )),
1372        }
1373    }
1374}
1375
1376#[cfg(feature = "geo-types")]
1377impl<'a> TryFrom<PostgresValue<'a>> for MultiPolygon<f64> {
1378    type Error = DrizzleError;
1379
1380    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1381        match value {
1382            PostgresValue::MultiPolygon(mp) => Ok(mp),
1383            _ => Err(DrizzleError::ConversionError(
1384                format!("Cannot convert {:?} to MultiPolygon", value).into(),
1385            )),
1386        }
1387    }
1388}
1389
1390// --- Bit String TryFrom implementations ---
1391
1392#[cfg(feature = "bitvec")]
1393impl<'a> TryFrom<PostgresValue<'a>> for BitVec {
1394    type Error = DrizzleError;
1395
1396    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1397        match value {
1398            PostgresValue::BitVec(bv) => Ok(bv),
1399            _ => Err(DrizzleError::ConversionError(
1400                format!("Cannot convert {:?} to BitVec", value).into(),
1401            )),
1402        }
1403    }
1404}
1405
1406// --- Array TryFrom implementations ---
1407
1408impl<'a> TryFrom<PostgresValue<'a>> for Vec<PostgresValue<'a>> {
1409    type Error = DrizzleError;
1410
1411    fn try_from(value: PostgresValue<'a>) -> Result<Self, Self::Error> {
1412        match value {
1413            PostgresValue::Array(arr) => Ok(arr),
1414            _ => Err(DrizzleError::ConversionError(
1415                format!("Cannot convert {:?} to Vec<PostgresValue>", value).into(),
1416            )),
1417        }
1418    }
1419}
1420
1421//------------------------------------------------------------------------------
1422// Database Driver Implementations
1423//------------------------------------------------------------------------------
1424
1425// SQLx implementations when the sqlx-postgres feature is enabled
1426#[cfg(feature = "sqlx-postgres")]
1427mod sqlx_impls {
1428    use super::*;
1429    use sqlx::{Encode, Postgres, Type, postgres::PgArgumentBuffer};
1430
1431    impl<'a> Type<Postgres> for PostgresValue<'a> {
1432        fn type_info() -> sqlx::postgres::PgTypeInfo {
1433            // This is a placeholder - in practice you'd need to handle different types
1434            <String as Type<Postgres>>::type_info()
1435        }
1436    }
1437
1438    impl<'a> Encode<'_, Postgres> for PostgresValue<'a> {
1439        fn encode_by_ref(
1440            &self,
1441            buf: &mut PgArgumentBuffer,
1442        ) -> Result<sqlx::encode::IsNull, Box<dyn std::error::Error + Send + Sync>> {
1443            match self {
1444                PostgresValue::Null => Ok(sqlx::encode::IsNull::Yes),
1445                PostgresValue::Integer(i) => i.encode_by_ref(buf),
1446                PostgresValue::Real(f) => f.encode_by_ref(buf),
1447                PostgresValue::Text(cow) => cow.as_ref().encode_by_ref(buf),
1448                PostgresValue::Bytea(cow) => cow.as_ref().encode_by_ref(buf),
1449                PostgresValue::Boolean(b) => b.encode_by_ref(buf),
1450                #[cfg(feature = "uuid")]
1451                PostgresValue::Uuid(uuid) => uuid.encode_by_ref(buf),
1452                #[cfg(feature = "serde")]
1453                PostgresValue::Json(json) => json.encode_by_ref(buf),
1454                PostgresValue::Enum(enum_val) => enum_val.variant_name().encode_by_ref(buf),
1455            }
1456        }
1457    }
1458}