Skip to main content

drizzle_postgres/values/
owned.rs

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