drizzle_postgres/values/
owned.rs

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