drizzle_postgres/values/
owned.rs

1//! Owned PostgreSQL value types for static lifetime scenarios
2
3use crate::PostgresValue;
4use drizzle_core::{SQLParam, error::DrizzleError};
5use std::borrow::Cow;
6#[cfg(feature = "uuid")]
7use uuid::Uuid;
8
9#[cfg(feature = "chrono")]
10use chrono::{DateTime, Duration, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime, Utc};
11
12#[cfg(feature = "rust_decimal")]
13use rust_decimal::Decimal;
14
15#[cfg(feature = "ipnet")]
16use ipnet::IpNet;
17
18#[cfg(feature = "geo-types")]
19use geo_types::{LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon};
20
21#[cfg(feature = "bitvec")]
22use bitvec::prelude::*;
23
24/// Owned version of PostgresValue that doesn't borrow data
25#[derive(Debug, Clone, PartialEq)]
26pub enum OwnedPostgresValue {
27    /// SMALLINT values (16-bit signed integer)
28    Smallint(i16),
29    /// INTEGER values (32-bit signed integer)
30    Integer(i32),
31    /// BIGINT values (64-bit signed integer)
32    Bigint(i64),
33    /// REAL values (32-bit floating point)
34    Real(f32),
35    /// DOUBLE PRECISION values (64-bit floating point)
36    DoublePrecision(f64),
37    /// TEXT, VARCHAR, CHAR values (owned)
38    Text(String),
39    /// BYTEA values (owned binary data)
40    Bytea(Vec<u8>),
41    /// BOOLEAN values
42    Boolean(bool),
43    /// UUID values
44    #[cfg(feature = "uuid")]
45    Uuid(Uuid),
46    /// JSON/JSONB values
47    #[cfg(feature = "serde")]
48    Json(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    // Numeric types
68    /// NUMERIC, DECIMAL values (arbitrary precision)
69    #[cfg(feature = "rust_decimal")]
70    Decimal(Decimal),
71
72    // Network address types
73    /// INET values (IPv4 or IPv6 networks)
74    #[cfg(feature = "ipnet")]
75    Inet(IpNet),
76    /// CIDR values (IPv4 or IPv6 networks)
77    #[cfg(feature = "ipnet")]
78    Cidr(IpNet),
79    /// MACADDR values (MAC addresses)
80    #[cfg(feature = "ipnet")]
81    MacAddr([u8; 6]),
82    /// MACADDR8 values (EUI-64 MAC addresses)
83    #[cfg(feature = "ipnet")]
84    MacAddr8([u8; 8]),
85
86    // Geometric types
87    /// POINT values
88    #[cfg(feature = "geo-types")]
89    Point(Point<f64>),
90    /// LINESTRING values
91    #[cfg(feature = "geo-types")]
92    LineString(LineString<f64>),
93    /// POLYGON values
94    #[cfg(feature = "geo-types")]
95    Polygon(Polygon<f64>),
96    /// MULTIPOINT values
97    #[cfg(feature = "geo-types")]
98    MultiPoint(MultiPoint<f64>),
99    /// MULTILINESTRING values
100    #[cfg(feature = "geo-types")]
101    MultiLineString(MultiLineString<f64>),
102    /// MULTIPOLYGON values
103    #[cfg(feature = "geo-types")]
104    MultiPolygon(MultiPolygon<f64>),
105
106    // Bit string types
107    /// BIT, BIT VARYING values
108    #[cfg(feature = "bitvec")]
109    BitVec(BitVec),
110
111    // Array types (using Vec for simplicity)
112    /// Array of any PostgreSQL type
113    Array(Vec<OwnedPostgresValue>),
114
115    /// NULL value
116    Null,
117}
118
119impl SQLParam for OwnedPostgresValue {}
120
121impl Default for OwnedPostgresValue {
122    fn default() -> Self {
123        OwnedPostgresValue::Null
124    }
125}
126
127impl std::fmt::Display for OwnedPostgresValue {
128    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129        let value = match self {
130            OwnedPostgresValue::Smallint(i) => i.to_string(),
131            OwnedPostgresValue::Integer(i) => i.to_string(),
132            OwnedPostgresValue::Bigint(i) => i.to_string(),
133            OwnedPostgresValue::Real(r) => r.to_string(),
134            OwnedPostgresValue::DoublePrecision(r) => r.to_string(),
135            OwnedPostgresValue::Text(s) => s.clone(),
136            OwnedPostgresValue::Bytea(b) => format!(
137                "\\x{}",
138                b.iter().map(|b| format!("{:02x}", b)).collect::<String>()
139            ),
140            OwnedPostgresValue::Boolean(b) => b.to_string(),
141            #[cfg(feature = "uuid")]
142            OwnedPostgresValue::Uuid(uuid) => uuid.to_string(),
143            #[cfg(feature = "serde")]
144            OwnedPostgresValue::Json(json) => json.to_string(),
145
146            // Date and time types
147            #[cfg(feature = "chrono")]
148            OwnedPostgresValue::Date(date) => date.format("%Y-%m-%d").to_string(),
149            #[cfg(feature = "chrono")]
150            OwnedPostgresValue::Time(time) => time.format("%H:%M:%S%.f").to_string(),
151            #[cfg(feature = "chrono")]
152            OwnedPostgresValue::Timestamp(ts) => ts.format("%Y-%m-%d %H:%M:%S%.f").to_string(),
153            #[cfg(feature = "chrono")]
154            OwnedPostgresValue::TimestampTz(ts) => {
155                ts.format("%Y-%m-%d %H:%M:%S%.f %:z").to_string()
156            }
157            #[cfg(feature = "chrono")]
158            OwnedPostgresValue::Interval(dur) => format!("{} seconds", dur.num_seconds()),
159
160            // Numeric types
161            #[cfg(feature = "rust_decimal")]
162            OwnedPostgresValue::Decimal(dec) => dec.to_string(),
163
164            // Network address types
165            #[cfg(feature = "ipnet")]
166            OwnedPostgresValue::Inet(net) => net.to_string(),
167            #[cfg(feature = "ipnet")]
168            OwnedPostgresValue::Cidr(net) => net.to_string(),
169            #[cfg(feature = "ipnet")]
170            OwnedPostgresValue::MacAddr(mac) => format!(
171                "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
172                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
173            ),
174            #[cfg(feature = "ipnet")]
175            OwnedPostgresValue::MacAddr8(mac) => format!(
176                "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
177                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mac[6], mac[7]
178            ),
179
180            // Geometric types
181            #[cfg(feature = "geo-types")]
182            OwnedPostgresValue::Point(point) => format!("({},{})", point.x(), point.y()),
183            #[cfg(feature = "geo-types")]
184            OwnedPostgresValue::LineString(line) => {
185                let coords: Vec<String> = line
186                    .coords()
187                    .map(|coord| format!("({},{})", coord.x, coord.y))
188                    .collect();
189                format!("[{}]", coords.join(","))
190            }
191            #[cfg(feature = "geo-types")]
192            OwnedPostgresValue::Polygon(poly) => format!(
193                "POLYGON({})",
194                poly.exterior()
195                    .coords()
196                    .map(|c| format!("({},{})", c.x, c.y))
197                    .collect::<Vec<_>>()
198                    .join(",")
199            ),
200            #[cfg(feature = "geo-types")]
201            OwnedPostgresValue::MultiPoint(mp) => format!(
202                "MULTIPOINT({})",
203                mp.iter()
204                    .map(|p| format!("({},{})", p.x(), p.y()))
205                    .collect::<Vec<_>>()
206                    .join(",")
207            ),
208            #[cfg(feature = "geo-types")]
209            OwnedPostgresValue::MultiLineString(mls) => format!(
210                "MULTILINESTRING({})",
211                mls.iter()
212                    .map(|ls| format!(
213                        "[{}]",
214                        ls.coords()
215                            .map(|c| format!("({},{})", c.x, c.y))
216                            .collect::<Vec<_>>()
217                            .join(",")
218                    ))
219                    .collect::<Vec<_>>()
220                    .join(",")
221            ),
222            #[cfg(feature = "geo-types")]
223            OwnedPostgresValue::MultiPolygon(mp) => format!(
224                "MULTIPOLYGON({})",
225                mp.iter()
226                    .map(|p| format!(
227                        "POLYGON({})",
228                        p.exterior()
229                            .coords()
230                            .map(|c| format!("({},{})", c.x, c.y))
231                            .collect::<Vec<_>>()
232                            .join(",")
233                    ))
234                    .collect::<Vec<_>>()
235                    .join(",")
236            ),
237
238            // Bit string types
239            #[cfg(feature = "bitvec")]
240            OwnedPostgresValue::BitVec(bv) => bv
241                .iter()
242                .map(|b| if *b { '1' } else { '0' })
243                .collect::<String>(),
244
245            // Array types
246            OwnedPostgresValue::Array(arr) => {
247                let elements: Vec<String> = arr.iter().map(|v| v.to_string()).collect();
248                format!("{{{}}}", elements.join(","))
249            }
250
251            OwnedPostgresValue::Null => String::new(),
252        };
253        write!(f, "{value}")
254    }
255}
256
257// Conversions from PostgresValue to OwnedPostgresValue
258impl<'a> From<PostgresValue<'a>> for OwnedPostgresValue {
259    fn from(value: PostgresValue<'a>) -> Self {
260        match value {
261            PostgresValue::Smallint(i) => OwnedPostgresValue::Smallint(i),
262            PostgresValue::Integer(i) => OwnedPostgresValue::Integer(i),
263            PostgresValue::Bigint(i) => OwnedPostgresValue::Bigint(i),
264            PostgresValue::Real(r) => OwnedPostgresValue::Real(r),
265            PostgresValue::DoublePrecision(r) => OwnedPostgresValue::DoublePrecision(r),
266            PostgresValue::Text(cow) => OwnedPostgresValue::Text(cow.into_owned()),
267            PostgresValue::Bytea(cow) => OwnedPostgresValue::Bytea(cow.into_owned()),
268            PostgresValue::Boolean(b) => OwnedPostgresValue::Boolean(b),
269            #[cfg(feature = "uuid")]
270            PostgresValue::Uuid(uuid) => OwnedPostgresValue::Uuid(uuid),
271            #[cfg(feature = "serde")]
272            PostgresValue::Json(json) => OwnedPostgresValue::Json(json),
273            PostgresValue::Enum(enum_val) => {
274                OwnedPostgresValue::Text(enum_val.variant_name().to_string())
275            }
276            PostgresValue::Null => OwnedPostgresValue::Null,
277            #[cfg(feature = "chrono")]
278            PostgresValue::Date(date) => OwnedPostgresValue::Date(date),
279            #[cfg(feature = "chrono")]
280            PostgresValue::Time(time) => OwnedPostgresValue::Time(time),
281            #[cfg(feature = "chrono")]
282            PostgresValue::Timestamp(ts) => OwnedPostgresValue::Timestamp(ts),
283            #[cfg(feature = "chrono")]
284            PostgresValue::TimestampTz(ts) => OwnedPostgresValue::TimestampTz(ts),
285            #[cfg(feature = "chrono")]
286            PostgresValue::Interval(dur) => OwnedPostgresValue::Interval(dur),
287            #[cfg(feature = "rust_decimal")]
288            PostgresValue::Decimal(dec) => OwnedPostgresValue::Decimal(dec),
289            #[cfg(feature = "ipnet")]
290            PostgresValue::Inet(net) => OwnedPostgresValue::Inet(net),
291            #[cfg(feature = "ipnet")]
292            PostgresValue::Cidr(net) => OwnedPostgresValue::Cidr(net),
293            #[cfg(feature = "ipnet")]
294            PostgresValue::MacAddr(mac) => OwnedPostgresValue::MacAddr(mac),
295            #[cfg(feature = "ipnet")]
296            PostgresValue::MacAddr8(mac) => OwnedPostgresValue::MacAddr8(mac),
297            #[cfg(feature = "geo-types")]
298            PostgresValue::Point(point) => OwnedPostgresValue::Point(point),
299            #[cfg(feature = "geo-types")]
300            PostgresValue::LineString(line) => OwnedPostgresValue::LineString(line),
301            #[cfg(feature = "geo-types")]
302            PostgresValue::Polygon(poly) => OwnedPostgresValue::Polygon(poly),
303            #[cfg(feature = "geo-types")]
304            PostgresValue::MultiPoint(mp) => OwnedPostgresValue::MultiPoint(mp),
305            #[cfg(feature = "geo-types")]
306            PostgresValue::MultiLineString(mls) => OwnedPostgresValue::MultiLineString(mls),
307            #[cfg(feature = "geo-types")]
308            PostgresValue::MultiPolygon(mp) => OwnedPostgresValue::MultiPolygon(mp),
309            #[cfg(feature = "bitvec")]
310            PostgresValue::BitVec(bv) => OwnedPostgresValue::BitVec(bv),
311            PostgresValue::Array(arr) => {
312                let owned_arr = arr
313                    .into_iter()
314                    .map(|v| OwnedPostgresValue::from(v))
315                    .collect();
316                OwnedPostgresValue::Array(owned_arr)
317            }
318        }
319    }
320}
321
322// Conversions from OwnedPostgresValue to PostgresValue
323impl<'a> From<OwnedPostgresValue> for PostgresValue<'a> {
324    fn from(value: OwnedPostgresValue) -> Self {
325        match value {
326            OwnedPostgresValue::Smallint(i) => PostgresValue::Smallint(i),
327            OwnedPostgresValue::Integer(i) => PostgresValue::Integer(i),
328            OwnedPostgresValue::Bigint(i) => PostgresValue::Bigint(i),
329            OwnedPostgresValue::Real(r) => PostgresValue::Real(r),
330            OwnedPostgresValue::DoublePrecision(r) => PostgresValue::DoublePrecision(r),
331            OwnedPostgresValue::Text(s) => PostgresValue::Text(Cow::Owned(s)),
332            OwnedPostgresValue::Bytea(b) => PostgresValue::Bytea(Cow::Owned(b)),
333            OwnedPostgresValue::Boolean(b) => PostgresValue::Boolean(b),
334            #[cfg(feature = "uuid")]
335            OwnedPostgresValue::Uuid(uuid) => PostgresValue::Uuid(uuid),
336            #[cfg(feature = "serde")]
337            OwnedPostgresValue::Json(json) => PostgresValue::Json(json),
338
339            // Date and time types
340            #[cfg(feature = "chrono")]
341            OwnedPostgresValue::Date(date) => PostgresValue::Date(date),
342            #[cfg(feature = "chrono")]
343            OwnedPostgresValue::Time(time) => PostgresValue::Time(time),
344            #[cfg(feature = "chrono")]
345            OwnedPostgresValue::Timestamp(ts) => PostgresValue::Timestamp(ts),
346            #[cfg(feature = "chrono")]
347            OwnedPostgresValue::TimestampTz(ts) => PostgresValue::TimestampTz(ts),
348            #[cfg(feature = "chrono")]
349            OwnedPostgresValue::Interval(dur) => PostgresValue::Interval(dur),
350            #[cfg(feature = "rust_decimal")]
351            OwnedPostgresValue::Decimal(dec) => PostgresValue::Decimal(dec),
352            #[cfg(feature = "ipnet")]
353            OwnedPostgresValue::Inet(net) => PostgresValue::Inet(net),
354            #[cfg(feature = "ipnet")]
355            OwnedPostgresValue::Cidr(net) => PostgresValue::Cidr(net),
356            #[cfg(feature = "ipnet")]
357            OwnedPostgresValue::MacAddr(mac) => PostgresValue::MacAddr(mac),
358            #[cfg(feature = "ipnet")]
359            OwnedPostgresValue::MacAddr8(mac) => PostgresValue::MacAddr8(mac),
360            #[cfg(feature = "geo-types")]
361            OwnedPostgresValue::Point(point) => PostgresValue::Point(point),
362            #[cfg(feature = "geo-types")]
363            OwnedPostgresValue::LineString(line) => PostgresValue::LineString(line),
364            #[cfg(feature = "geo-types")]
365            OwnedPostgresValue::Polygon(poly) => PostgresValue::Polygon(poly),
366            #[cfg(feature = "geo-types")]
367            OwnedPostgresValue::MultiPoint(mp) => PostgresValue::MultiPoint(mp),
368            #[cfg(feature = "geo-types")]
369            OwnedPostgresValue::MultiLineString(mls) => PostgresValue::MultiLineString(mls),
370            #[cfg(feature = "geo-types")]
371            OwnedPostgresValue::MultiPolygon(mp) => PostgresValue::MultiPolygon(mp),
372            #[cfg(feature = "bitvec")]
373            OwnedPostgresValue::BitVec(bv) => PostgresValue::BitVec(bv),
374            OwnedPostgresValue::Array(arr) => {
375                let postgres_arr = arr.into_iter().map(|v| PostgresValue::from(v)).collect();
376                PostgresValue::Array(postgres_arr)
377            }
378
379            OwnedPostgresValue::Null => PostgresValue::Null,
380        }
381    }
382}
383
384// Direct conversions from Rust types to OwnedPostgresValue
385impl From<i16> for OwnedPostgresValue {
386    fn from(value: i16) -> Self {
387        OwnedPostgresValue::Smallint(value)
388    }
389}
390
391impl From<i32> for OwnedPostgresValue {
392    fn from(value: i32) -> Self {
393        OwnedPostgresValue::Integer(value)
394    }
395}
396
397impl From<i64> for OwnedPostgresValue {
398    fn from(value: i64) -> Self {
399        OwnedPostgresValue::Bigint(value)
400    }
401}
402
403impl From<f32> for OwnedPostgresValue {
404    fn from(value: f32) -> Self {
405        OwnedPostgresValue::Real(value)
406    }
407}
408
409impl From<f64> for OwnedPostgresValue {
410    fn from(value: f64) -> Self {
411        OwnedPostgresValue::DoublePrecision(value)
412    }
413}
414
415impl From<String> for OwnedPostgresValue {
416    fn from(value: String) -> Self {
417        OwnedPostgresValue::Text(value)
418    }
419}
420
421impl From<Vec<u8>> for OwnedPostgresValue {
422    fn from(value: Vec<u8>) -> Self {
423        OwnedPostgresValue::Bytea(value)
424    }
425}
426
427impl From<bool> for OwnedPostgresValue {
428    fn from(value: bool) -> Self {
429        OwnedPostgresValue::Boolean(value)
430    }
431}
432
433#[cfg(feature = "uuid")]
434impl From<Uuid> for OwnedPostgresValue {
435    fn from(value: Uuid) -> Self {
436        OwnedPostgresValue::Uuid(value)
437    }
438}
439
440#[cfg(feature = "serde")]
441impl From<serde_json::Value> for OwnedPostgresValue {
442    fn from(value: serde_json::Value) -> Self {
443        OwnedPostgresValue::Json(value)
444    }
445}
446
447// TryFrom conversions back to Rust types
448impl TryFrom<OwnedPostgresValue> for i16 {
449    type Error = DrizzleError;
450
451    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
452        match value {
453            OwnedPostgresValue::Smallint(i) => Ok(i),
454            OwnedPostgresValue::Integer(i) => Ok(i.try_into()?),
455            OwnedPostgresValue::Bigint(i) => Ok(i.try_into()?),
456            _ => Err(DrizzleError::ConversionError(
457                format!("Cannot convert {:?} to i16", value).into(),
458            )),
459        }
460    }
461}
462
463impl TryFrom<OwnedPostgresValue> for i32 {
464    type Error = DrizzleError;
465
466    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
467        match value {
468            OwnedPostgresValue::Smallint(i) => Ok(i.into()),
469            OwnedPostgresValue::Integer(i) => Ok(i),
470            OwnedPostgresValue::Bigint(i) => Ok(i.try_into()?),
471            _ => Err(DrizzleError::ConversionError(
472                format!("Cannot convert {:?} to i32", value).into(),
473            )),
474        }
475    }
476}
477
478impl TryFrom<OwnedPostgresValue> for i64 {
479    type Error = DrizzleError;
480
481    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
482        match value {
483            OwnedPostgresValue::Smallint(i) => Ok(i.into()),
484            OwnedPostgresValue::Integer(i) => Ok(i.into()),
485            OwnedPostgresValue::Bigint(i) => Ok(i),
486            _ => Err(DrizzleError::ConversionError(
487                format!("Cannot convert {:?} to i64", value).into(),
488            )),
489        }
490    }
491}
492
493impl TryFrom<OwnedPostgresValue> for f32 {
494    type Error = DrizzleError;
495
496    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
497        match value {
498            OwnedPostgresValue::Real(r) => Ok(r),
499            OwnedPostgresValue::DoublePrecision(r) => Ok(r as f32),
500            OwnedPostgresValue::Smallint(i) => Ok(i as f32),
501            OwnedPostgresValue::Integer(i) => Ok(i as f32),
502            OwnedPostgresValue::Bigint(i) => Ok(i as f32),
503            _ => Err(DrizzleError::ConversionError(
504                format!("Cannot convert {:?} to f32", value).into(),
505            )),
506        }
507    }
508}
509
510impl TryFrom<OwnedPostgresValue> for f64 {
511    type Error = DrizzleError;
512
513    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
514        match value {
515            OwnedPostgresValue::Real(r) => Ok(r as f64),
516            OwnedPostgresValue::DoublePrecision(r) => Ok(r),
517            OwnedPostgresValue::Smallint(i) => Ok(i as f64),
518            OwnedPostgresValue::Integer(i) => Ok(i as f64),
519            OwnedPostgresValue::Bigint(i) => Ok(i as f64),
520            _ => Err(DrizzleError::ConversionError(
521                format!("Cannot convert {:?} to f64", value).into(),
522            )),
523        }
524    }
525}
526
527impl TryFrom<OwnedPostgresValue> for String {
528    type Error = DrizzleError;
529
530    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
531        match value {
532            OwnedPostgresValue::Text(s) => Ok(s),
533            _ => Err(DrizzleError::ConversionError(
534                format!("Cannot convert {:?} to String", value).into(),
535            )),
536        }
537    }
538}
539
540impl TryFrom<OwnedPostgresValue> for Vec<u8> {
541    type Error = DrizzleError;
542
543    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
544        match value {
545            OwnedPostgresValue::Bytea(b) => Ok(b),
546            _ => Err(DrizzleError::ConversionError(
547                format!("Cannot convert {:?} to Vec<u8>", value).into(),
548            )),
549        }
550    }
551}
552
553impl TryFrom<OwnedPostgresValue> for bool {
554    type Error = DrizzleError;
555
556    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
557        match value {
558            OwnedPostgresValue::Boolean(b) => Ok(b),
559            _ => Err(DrizzleError::ConversionError(
560                format!("Cannot convert {:?} to bool", value).into(),
561            )),
562        }
563    }
564}
565
566#[cfg(feature = "uuid")]
567impl TryFrom<OwnedPostgresValue> for Uuid {
568    type Error = DrizzleError;
569
570    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
571        match value {
572            OwnedPostgresValue::Uuid(uuid) => Ok(uuid),
573            OwnedPostgresValue::Text(s) => Ok(Uuid::parse_str(&s)?),
574            _ => Err(DrizzleError::ConversionError(
575                format!("Cannot convert {:?} to UUID", value).into(),
576            )),
577        }
578    }
579}
580
581#[cfg(feature = "serde")]
582impl TryFrom<OwnedPostgresValue> for serde_json::Value {
583    type Error = DrizzleError;
584
585    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
586        match value {
587            OwnedPostgresValue::Json(json) => Ok(json),
588            OwnedPostgresValue::Text(s) => serde_json::from_str(&s).map_err(|e| {
589                DrizzleError::ConversionError(format!("Failed to parse JSON: {}", e).into())
590            }),
591            _ => Err(DrizzleError::ConversionError(
592                format!("Cannot convert {:?} to JSON", value).into(),
593            )),
594        }
595    }
596}