Skip to main content

drizzle_postgres/values/
owned.rs

1//! Owned `PostgreSQL` value types for static lifetime scenarios
2
3use super::PostgresValue;
4use crate::prelude::*;
5use crate::traits::{FromPostgresValue, PostgresEnum};
6use drizzle_core::{SQLParam, error::DrizzleError, sql::SQL};
7#[cfg(feature = "uuid")]
8use uuid::Uuid;
9
10#[cfg(feature = "chrono")]
11use chrono::{DateTime, Duration, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime};
12
13#[cfg(feature = "time")]
14use time::{
15    Date as TimeDate, Duration as TimeDuration, OffsetDateTime, PrimitiveDateTime, Time as TimeTime,
16};
17
18#[cfg(feature = "cidr")]
19use cidr::{IpCidr, IpInet};
20
21#[cfg(feature = "geo-types")]
22use geo_types::{LineString, Point, Rect};
23
24#[cfg(feature = "bit-vec")]
25use bit_vec::BitVec;
26
27#[cfg(feature = "rust-decimal")]
28use rust_decimal::Decimal;
29
30/// Owned version of `PostgresValue` that doesn't borrow data
31#[derive(Debug, Clone, PartialEq, Default)]
32pub enum OwnedPostgresValue {
33    /// SMALLINT values (16-bit signed integer)
34    Smallint(i16),
35    /// INTEGER values (32-bit signed integer)
36    Integer(i32),
37    /// BIGINT values (64-bit signed integer)
38    Bigint(i64),
39    /// REAL values (32-bit floating point)
40    Real(f32),
41    /// DOUBLE PRECISION values (64-bit floating point)
42    DoublePrecision(f64),
43    /// NUMERIC/DECIMAL values
44    #[cfg(feature = "rust-decimal")]
45    Numeric(Decimal),
46    /// TEXT, VARCHAR, CHAR values (owned)
47    Text(String),
48    /// BYTEA values (owned binary data)
49    Bytea(Vec<u8>),
50    /// BOOLEAN values
51    Boolean(bool),
52    /// UUID values
53    #[cfg(feature = "uuid")]
54    Uuid(Uuid),
55    /// JSON values (stored as text in `PostgreSQL`)
56    #[cfg(feature = "serde")]
57    Json(serde_json::Value),
58    /// JSONB values (stored as binary in `PostgreSQL`)
59    #[cfg(feature = "serde")]
60    Jsonb(serde_json::Value),
61
62    // Date and time types
63    /// DATE values
64    #[cfg(feature = "chrono")]
65    Date(NaiveDate),
66    /// TIME values
67    #[cfg(feature = "chrono")]
68    Time(NaiveTime),
69    /// TIMESTAMP values (without timezone)
70    #[cfg(feature = "chrono")]
71    Timestamp(NaiveDateTime),
72    /// TIMESTAMPTZ values (with timezone)
73    #[cfg(feature = "chrono")]
74    TimestampTz(DateTime<FixedOffset>),
75    /// INTERVAL values
76    #[cfg(feature = "chrono")]
77    Interval(Duration),
78
79    // Date and time types (time crate)
80    /// DATE values (time crate)
81    #[cfg(feature = "time")]
82    TimeDate(TimeDate),
83    /// TIME values (time crate)
84    #[cfg(feature = "time")]
85    TimeTime(TimeTime),
86    /// TIMESTAMP values without timezone (time crate)
87    #[cfg(feature = "time")]
88    TimeTimestamp(PrimitiveDateTime),
89    /// TIMESTAMPTZ values with timezone (time crate)
90    #[cfg(feature = "time")]
91    TimeTimestampTz(OffsetDateTime),
92    /// INTERVAL values (time crate)
93    #[cfg(feature = "time")]
94    TimeInterval(TimeDuration),
95
96    // Network address types
97    /// INET values (host address with optional netmask)
98    #[cfg(feature = "cidr")]
99    Inet(IpInet),
100    /// CIDR values (network specification)
101    #[cfg(feature = "cidr")]
102    Cidr(IpCidr),
103    /// MACADDR values (MAC addresses)
104    #[cfg(feature = "cidr")]
105    MacAddr([u8; 6]),
106    /// MACADDR8 values (EUI-64 MAC addresses)
107    #[cfg(feature = "cidr")]
108    MacAddr8([u8; 8]),
109
110    // Geometric types (native PostgreSQL support via postgres-rs)
111    /// POINT values
112    #[cfg(feature = "geo-types")]
113    Point(Point<f64>),
114    /// PATH values (open path from `LineString`)
115    #[cfg(feature = "geo-types")]
116    LineString(LineString<f64>),
117    /// BOX values (bounding rectangle)
118    #[cfg(feature = "geo-types")]
119    Rect(Rect<f64>),
120
121    // Bit string types
122    /// BIT, BIT VARYING values
123    #[cfg(feature = "bit-vec")]
124    BitVec(BitVec),
125
126    // Array types (using Vec for simplicity)
127    /// Array of any `PostgreSQL` type
128    Array(Vec<Self>),
129
130    /// `PostgreSQL` ENUM values (native enum types via `CREATE TYPE ... AS ENUM`)
131    Enum(Box<dyn PostgresEnum>),
132
133    /// NULL value
134    #[default]
135    Null,
136}
137
138impl SQLParam for OwnedPostgresValue {
139    const DIALECT: drizzle_core::Dialect = drizzle_core::Dialect::PostgreSQL;
140    type DialectMarker = drizzle_core::dialect::PostgresDialect;
141}
142
143impl From<OwnedPostgresValue> for SQL<'_, OwnedPostgresValue> {
144    fn from(value: OwnedPostgresValue) -> Self {
145        SQL::param(value)
146    }
147}
148
149impl From<OwnedPostgresValue> for Cow<'_, OwnedPostgresValue> {
150    fn from(value: OwnedPostgresValue) -> Self {
151        Cow::Owned(value)
152    }
153}
154
155impl<'a> From<&'a OwnedPostgresValue> for Cow<'a, OwnedPostgresValue> {
156    fn from(value: &'a OwnedPostgresValue) -> Self {
157        Cow::Borrowed(value)
158    }
159}
160
161impl OwnedPostgresValue {
162    /// Returns true if this value is NULL.
163    #[inline]
164    #[must_use]
165    pub const fn is_null(&self) -> bool {
166        matches!(self, Self::Null)
167    }
168
169    /// Returns the boolean value if this is BOOLEAN.
170    #[inline]
171    #[must_use]
172    pub const fn as_bool(&self) -> Option<bool> {
173        match self {
174            Self::Boolean(value) => Some(*value),
175            _ => None,
176        }
177    }
178
179    /// Returns the i16 value if this is SMALLINT.
180    #[inline]
181    #[must_use]
182    pub const fn as_i16(&self) -> Option<i16> {
183        match self {
184            Self::Smallint(value) => Some(*value),
185            _ => None,
186        }
187    }
188
189    /// Returns the i32 value if this is INTEGER.
190    #[inline]
191    #[must_use]
192    pub const fn as_i32(&self) -> Option<i32> {
193        match self {
194            Self::Integer(value) => Some(*value),
195            _ => None,
196        }
197    }
198
199    /// Returns the i64 value if this is BIGINT.
200    #[inline]
201    #[must_use]
202    pub const fn as_i64(&self) -> Option<i64> {
203        match self {
204            Self::Bigint(value) => Some(*value),
205            _ => None,
206        }
207    }
208
209    /// Returns the f32 value if this is REAL.
210    #[inline]
211    #[must_use]
212    pub const fn as_f32(&self) -> Option<f32> {
213        match self {
214            Self::Real(value) => Some(*value),
215            _ => None,
216        }
217    }
218
219    /// Returns the f64 value if this is DOUBLE PRECISION.
220    #[inline]
221    #[must_use]
222    pub const fn as_f64(&self) -> Option<f64> {
223        match self {
224            Self::DoublePrecision(value) => Some(*value),
225            _ => None,
226        }
227    }
228
229    /// Returns the decimal value if this is NUMERIC.
230    #[inline]
231    #[cfg(feature = "rust-decimal")]
232    #[must_use]
233    pub const fn as_decimal(&self) -> Option<&Decimal> {
234        match self {
235            Self::Numeric(value) => Some(value),
236            _ => None,
237        }
238    }
239
240    /// Returns the text value if this is TEXT.
241    #[inline]
242    #[must_use]
243    pub const fn as_str(&self) -> Option<&str> {
244        match self {
245            Self::Text(value) => Some(value.as_str()),
246            _ => None,
247        }
248    }
249
250    /// Returns the bytea value if this is BYTEA.
251    #[inline]
252    #[must_use]
253    pub fn as_bytes(&self) -> Option<&[u8]> {
254        match self {
255            Self::Bytea(value) => Some(value.as_ref()),
256            _ => None,
257        }
258    }
259
260    /// Returns the UUID value if this is UUID.
261    #[inline]
262    #[cfg(feature = "uuid")]
263    #[must_use]
264    pub const fn as_uuid(&self) -> Option<Uuid> {
265        match self {
266            Self::Uuid(value) => Some(*value),
267            _ => None,
268        }
269    }
270
271    /// Returns the JSON value if this is JSON.
272    #[inline]
273    #[cfg(feature = "serde")]
274    #[must_use]
275    pub const fn as_json(&self) -> Option<&serde_json::Value> {
276        match self {
277            Self::Json(value) => Some(value),
278            _ => None,
279        }
280    }
281
282    /// Returns the JSONB value if this is JSONB.
283    #[inline]
284    #[cfg(feature = "serde")]
285    #[must_use]
286    pub const fn as_jsonb(&self) -> Option<&serde_json::Value> {
287        match self {
288            Self::Jsonb(value) => Some(value),
289            _ => None,
290        }
291    }
292
293    /// Returns the date value if this is DATE.
294    #[inline]
295    #[cfg(feature = "chrono")]
296    #[must_use]
297    pub const fn as_date(&self) -> Option<&NaiveDate> {
298        match self {
299            Self::Date(value) => Some(value),
300            _ => None,
301        }
302    }
303
304    /// Returns the time value if this is TIME.
305    #[inline]
306    #[cfg(feature = "chrono")]
307    #[must_use]
308    pub const fn as_time(&self) -> Option<&NaiveTime> {
309        match self {
310            Self::Time(value) => Some(value),
311            _ => None,
312        }
313    }
314
315    /// Returns the timestamp value if this is TIMESTAMP.
316    #[inline]
317    #[cfg(feature = "chrono")]
318    #[must_use]
319    pub const fn as_timestamp(&self) -> Option<&NaiveDateTime> {
320        match self {
321            Self::Timestamp(value) => Some(value),
322            _ => None,
323        }
324    }
325
326    /// Returns the timestamp with timezone value if this is TIMESTAMPTZ.
327    #[inline]
328    #[cfg(feature = "chrono")]
329    #[must_use]
330    pub const fn as_timestamp_tz(&self) -> Option<&DateTime<FixedOffset>> {
331        match self {
332            Self::TimestampTz(value) => Some(value),
333            _ => None,
334        }
335    }
336
337    /// Returns the interval value if this is INTERVAL.
338    #[inline]
339    #[cfg(feature = "chrono")]
340    #[must_use]
341    pub const fn as_interval(&self) -> Option<&Duration> {
342        match self {
343            Self::Interval(value) => Some(value),
344            _ => None,
345        }
346    }
347
348    /// Returns the date value if this is DATE (time crate).
349    #[inline]
350    #[cfg(feature = "time")]
351    #[must_use]
352    pub const fn as_time_date(&self) -> Option<&TimeDate> {
353        match self {
354            Self::TimeDate(value) => Some(value),
355            _ => None,
356        }
357    }
358
359    /// Returns the time value if this is TIME (time crate).
360    #[inline]
361    #[cfg(feature = "time")]
362    #[must_use]
363    pub const fn as_time_time(&self) -> Option<&TimeTime> {
364        match self {
365            Self::TimeTime(value) => Some(value),
366            _ => None,
367        }
368    }
369
370    /// Returns the timestamp value if this is TIMESTAMP (time crate).
371    #[inline]
372    #[cfg(feature = "time")]
373    #[must_use]
374    pub const fn as_time_timestamp(&self) -> Option<&PrimitiveDateTime> {
375        match self {
376            Self::TimeTimestamp(value) => Some(value),
377            _ => None,
378        }
379    }
380
381    /// Returns the timestamp with timezone value if this is TIMESTAMPTZ (time crate).
382    #[inline]
383    #[cfg(feature = "time")]
384    #[must_use]
385    pub const fn as_time_timestamp_tz(&self) -> Option<&OffsetDateTime> {
386        match self {
387            Self::TimeTimestampTz(value) => Some(value),
388            _ => None,
389        }
390    }
391
392    /// Returns the interval value if this is INTERVAL (time crate).
393    #[inline]
394    #[cfg(feature = "time")]
395    #[must_use]
396    pub const fn as_time_interval(&self) -> Option<&TimeDuration> {
397        match self {
398            Self::TimeInterval(value) => Some(value),
399            _ => None,
400        }
401    }
402
403    /// Returns the inet value if this is INET.
404    #[inline]
405    #[cfg(feature = "cidr")]
406    #[must_use]
407    pub const fn as_inet(&self) -> Option<&IpInet> {
408        match self {
409            Self::Inet(value) => Some(value),
410            _ => None,
411        }
412    }
413
414    /// Returns the cidr value if this is CIDR.
415    #[inline]
416    #[cfg(feature = "cidr")]
417    #[must_use]
418    pub const fn as_cidr(&self) -> Option<&IpCidr> {
419        match self {
420            Self::Cidr(value) => Some(value),
421            _ => None,
422        }
423    }
424
425    /// Returns the MAC address if this is MACADDR.
426    #[inline]
427    #[cfg(feature = "cidr")]
428    #[must_use]
429    pub const fn as_macaddr(&self) -> Option<[u8; 6]> {
430        match self {
431            Self::MacAddr(value) => Some(*value),
432            _ => None,
433        }
434    }
435
436    /// Returns the MAC address if this is MACADDR8.
437    #[inline]
438    #[cfg(feature = "cidr")]
439    #[must_use]
440    pub const fn as_macaddr8(&self) -> Option<[u8; 8]> {
441        match self {
442            Self::MacAddr8(value) => Some(*value),
443            _ => None,
444        }
445    }
446
447    /// Returns the point value if this is POINT.
448    #[inline]
449    #[cfg(feature = "geo-types")]
450    #[must_use]
451    pub const fn as_point(&self) -> Option<&Point<f64>> {
452        match self {
453            Self::Point(value) => Some(value),
454            _ => None,
455        }
456    }
457
458    /// Returns the line string value if this is PATH.
459    #[inline]
460    #[cfg(feature = "geo-types")]
461    #[must_use]
462    pub const fn as_line_string(&self) -> Option<&LineString<f64>> {
463        match self {
464            Self::LineString(value) => Some(value),
465            _ => None,
466        }
467    }
468
469    /// Returns the rect value if this is BOX.
470    #[inline]
471    #[cfg(feature = "geo-types")]
472    #[must_use]
473    pub const fn as_rect(&self) -> Option<&Rect<f64>> {
474        match self {
475            Self::Rect(value) => Some(value),
476            _ => None,
477        }
478    }
479
480    /// Returns the bit vector if this is BIT/VARBIT.
481    #[inline]
482    #[cfg(feature = "bit-vec")]
483    #[must_use]
484    pub const fn as_bitvec(&self) -> Option<&BitVec> {
485        match self {
486            Self::BitVec(value) => Some(value),
487            _ => None,
488        }
489    }
490
491    /// Returns the array elements if this is an ARRAY.
492    #[inline]
493    #[must_use]
494    pub fn as_array(&self) -> Option<&[Self]> {
495        match self {
496            Self::Array(values) => Some(values),
497            _ => None,
498        }
499    }
500
501    /// Returns a borrowed `PostgresValue` view of this owned value.
502    #[inline]
503    pub fn as_value(&self) -> PostgresValue<'_> {
504        match self {
505            Self::Smallint(value) => PostgresValue::Smallint(*value),
506            Self::Integer(value) => PostgresValue::Integer(*value),
507            Self::Bigint(value) => PostgresValue::Bigint(*value),
508            Self::Real(value) => PostgresValue::Real(*value),
509            Self::DoublePrecision(value) => PostgresValue::DoublePrecision(*value),
510            #[cfg(feature = "rust-decimal")]
511            Self::Numeric(value) => PostgresValue::Numeric(*value),
512            Self::Text(value) => PostgresValue::Text(Cow::Borrowed(value)),
513            Self::Bytea(value) => PostgresValue::Bytea(Cow::Borrowed(value)),
514            Self::Boolean(value) => PostgresValue::Boolean(*value),
515            #[cfg(feature = "uuid")]
516            Self::Uuid(value) => PostgresValue::Uuid(*value),
517            #[cfg(feature = "serde")]
518            Self::Json(value) => PostgresValue::Json(value.clone()),
519            #[cfg(feature = "serde")]
520            Self::Jsonb(value) => PostgresValue::Jsonb(value.clone()),
521            #[cfg(feature = "chrono")]
522            Self::Date(value) => PostgresValue::Date(*value),
523            #[cfg(feature = "chrono")]
524            Self::Time(value) => PostgresValue::Time(*value),
525            #[cfg(feature = "chrono")]
526            Self::Timestamp(value) => PostgresValue::Timestamp(*value),
527            #[cfg(feature = "chrono")]
528            Self::TimestampTz(value) => PostgresValue::TimestampTz(*value),
529            #[cfg(feature = "chrono")]
530            Self::Interval(value) => PostgresValue::Interval(*value),
531            #[cfg(feature = "time")]
532            Self::TimeDate(value) => PostgresValue::TimeDate(*value),
533            #[cfg(feature = "time")]
534            Self::TimeTime(value) => PostgresValue::TimeTime(*value),
535            #[cfg(feature = "time")]
536            Self::TimeTimestamp(value) => PostgresValue::TimeTimestamp(*value),
537            #[cfg(feature = "time")]
538            Self::TimeTimestampTz(value) => PostgresValue::TimeTimestampTz(*value),
539            #[cfg(feature = "time")]
540            Self::TimeInterval(value) => PostgresValue::TimeInterval(*value),
541            #[cfg(feature = "cidr")]
542            Self::Inet(value) => PostgresValue::Inet(*value),
543            #[cfg(feature = "cidr")]
544            Self::Cidr(value) => PostgresValue::Cidr(*value),
545            #[cfg(feature = "cidr")]
546            Self::MacAddr(value) => PostgresValue::MacAddr(*value),
547            #[cfg(feature = "cidr")]
548            Self::MacAddr8(value) => PostgresValue::MacAddr8(*value),
549            #[cfg(feature = "geo-types")]
550            Self::Point(value) => PostgresValue::Point(*value),
551            #[cfg(feature = "geo-types")]
552            Self::LineString(value) => PostgresValue::LineString(value.clone()),
553            #[cfg(feature = "geo-types")]
554            Self::Rect(value) => PostgresValue::Rect(*value),
555            #[cfg(feature = "bit-vec")]
556            Self::BitVec(value) => PostgresValue::BitVec(value.clone()),
557            Self::Array(values) => {
558                PostgresValue::Array(values.iter().map(Self::as_value).collect())
559            }
560            Self::Enum(value) => PostgresValue::Enum(value.clone()),
561            Self::Null => PostgresValue::Null,
562        }
563    }
564
565    /// Convert this `PostgreSQL` value to a Rust type using the `FromPostgresValue` trait.
566    ///
567    /// # Errors
568    ///
569    /// Returns [`DrizzleError::ConversionError`] when the stored variant's
570    /// native type does not match the target type `T`.
571    pub fn convert<T: FromPostgresValue>(self) -> Result<T, DrizzleError> {
572        match self {
573            Self::Boolean(value) => T::from_postgres_bool(value),
574            Self::Smallint(value) => T::from_postgres_i16(value),
575            Self::Integer(value) => T::from_postgres_i32(value),
576            Self::Bigint(value) => T::from_postgres_i64(value),
577            Self::Real(value) => T::from_postgres_f32(value),
578            Self::DoublePrecision(value) => T::from_postgres_f64(value),
579            #[cfg(feature = "rust-decimal")]
580            Self::Numeric(value) => {
581                let text = value.to_string();
582                T::from_postgres_text(&text)
583            }
584            Self::Text(value) => T::from_postgres_text(&value),
585            Self::Bytea(value) => T::from_postgres_bytes(&value),
586            #[cfg(feature = "uuid")]
587            Self::Uuid(value) => T::from_postgres_uuid(value),
588            #[cfg(feature = "serde")]
589            Self::Json(value) => T::from_postgres_json(value),
590            #[cfg(feature = "serde")]
591            Self::Jsonb(value) => T::from_postgres_jsonb(value),
592            #[cfg(feature = "chrono")]
593            Self::Date(value) => T::from_postgres_date(value),
594            #[cfg(feature = "chrono")]
595            Self::Time(value) => T::from_postgres_time(value),
596            #[cfg(feature = "chrono")]
597            Self::Timestamp(value) => T::from_postgres_timestamp(value),
598            #[cfg(feature = "chrono")]
599            Self::TimestampTz(value) => T::from_postgres_timestamptz(value),
600            #[cfg(feature = "chrono")]
601            Self::Interval(value) => T::from_postgres_interval(value),
602            #[cfg(feature = "time")]
603            Self::TimeDate(value) => T::from_postgres_time_date(value),
604            #[cfg(feature = "time")]
605            Self::TimeTime(value) => T::from_postgres_time_time(value),
606            #[cfg(feature = "time")]
607            Self::TimeTimestamp(value) => T::from_postgres_time_timestamp(value),
608            #[cfg(feature = "time")]
609            Self::TimeTimestampTz(value) => T::from_postgres_time_timestamptz(value),
610            #[cfg(feature = "time")]
611            Self::TimeInterval(value) => T::from_postgres_time_interval(value),
612            #[cfg(feature = "cidr")]
613            Self::Inet(value) => T::from_postgres_inet(value),
614            #[cfg(feature = "cidr")]
615            Self::Cidr(value) => T::from_postgres_cidr(value),
616            #[cfg(feature = "cidr")]
617            Self::MacAddr(value) => T::from_postgres_macaddr(value),
618            #[cfg(feature = "cidr")]
619            Self::MacAddr8(value) => T::from_postgres_macaddr8(value),
620            #[cfg(feature = "geo-types")]
621            Self::Point(value) => T::from_postgres_point(value),
622            #[cfg(feature = "geo-types")]
623            Self::LineString(value) => T::from_postgres_linestring(value),
624            #[cfg(feature = "geo-types")]
625            Self::Rect(value) => T::from_postgres_rect(value),
626            #[cfg(feature = "bit-vec")]
627            Self::BitVec(value) => T::from_postgres_bitvec(value),
628            Self::Array(values) => {
629                let values = values.into_iter().map(PostgresValue::from).collect();
630                T::from_postgres_array(values)
631            }
632            Self::Enum(value) => T::from_postgres_text(value.variant_name()),
633            Self::Null => T::from_postgres_null(),
634        }
635    }
636
637    /// Convert a reference to this `PostgreSQL` value to a Rust type.
638    ///
639    /// # Errors
640    ///
641    /// Returns [`DrizzleError::ConversionError`] when the stored variant's
642    /// native type does not match the target type `T`.
643    pub fn convert_ref<T: FromPostgresValue>(&self) -> Result<T, DrizzleError> {
644        match self {
645            Self::Boolean(value) => T::from_postgres_bool(*value),
646            Self::Smallint(value) => T::from_postgres_i16(*value),
647            Self::Integer(value) => T::from_postgres_i32(*value),
648            Self::Bigint(value) => T::from_postgres_i64(*value),
649            Self::Real(value) => T::from_postgres_f32(*value),
650            Self::DoublePrecision(value) => T::from_postgres_f64(*value),
651            #[cfg(feature = "rust-decimal")]
652            Self::Numeric(value) => {
653                let text = value.to_string();
654                T::from_postgres_text(&text)
655            }
656            Self::Text(value) => T::from_postgres_text(value),
657            Self::Bytea(value) => T::from_postgres_bytes(value),
658            #[cfg(feature = "uuid")]
659            Self::Uuid(value) => T::from_postgres_uuid(*value),
660            #[cfg(feature = "serde")]
661            Self::Json(value) => T::from_postgres_json(value.clone()),
662            #[cfg(feature = "serde")]
663            Self::Jsonb(value) => T::from_postgres_jsonb(value.clone()),
664            #[cfg(feature = "chrono")]
665            Self::Date(value) => T::from_postgres_date(*value),
666            #[cfg(feature = "chrono")]
667            Self::Time(value) => T::from_postgres_time(*value),
668            #[cfg(feature = "chrono")]
669            Self::Timestamp(value) => T::from_postgres_timestamp(*value),
670            #[cfg(feature = "chrono")]
671            Self::TimestampTz(value) => T::from_postgres_timestamptz(*value),
672            #[cfg(feature = "chrono")]
673            Self::Interval(value) => T::from_postgres_interval(*value),
674            #[cfg(feature = "time")]
675            Self::TimeDate(value) => T::from_postgres_time_date(*value),
676            #[cfg(feature = "time")]
677            Self::TimeTime(value) => T::from_postgres_time_time(*value),
678            #[cfg(feature = "time")]
679            Self::TimeTimestamp(value) => T::from_postgres_time_timestamp(*value),
680            #[cfg(feature = "time")]
681            Self::TimeTimestampTz(value) => T::from_postgres_time_timestamptz(*value),
682            #[cfg(feature = "time")]
683            Self::TimeInterval(value) => T::from_postgres_time_interval(*value),
684            #[cfg(feature = "cidr")]
685            Self::Inet(value) => T::from_postgres_inet(*value),
686            #[cfg(feature = "cidr")]
687            Self::Cidr(value) => T::from_postgres_cidr(*value),
688            #[cfg(feature = "cidr")]
689            Self::MacAddr(value) => T::from_postgres_macaddr(*value),
690            #[cfg(feature = "cidr")]
691            Self::MacAddr8(value) => T::from_postgres_macaddr8(*value),
692            #[cfg(feature = "geo-types")]
693            Self::Point(value) => T::from_postgres_point(*value),
694            #[cfg(feature = "geo-types")]
695            Self::LineString(value) => T::from_postgres_linestring(value.clone()),
696            #[cfg(feature = "geo-types")]
697            Self::Rect(value) => T::from_postgres_rect(*value),
698            #[cfg(feature = "bit-vec")]
699            Self::BitVec(value) => T::from_postgres_bitvec(value.clone()),
700            Self::Array(values) => {
701                let values = values.iter().map(Self::as_value).collect();
702                T::from_postgres_array(values)
703            }
704            Self::Enum(value) => T::from_postgres_text(value.variant_name()),
705            Self::Null => T::from_postgres_null(),
706        }
707    }
708}
709
710impl core::fmt::Display for OwnedPostgresValue {
711    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
712        let value = match self {
713            Self::Smallint(i) => i.to_string(),
714            Self::Integer(i) => i.to_string(),
715            Self::Bigint(i) => i.to_string(),
716            Self::Real(r) => r.to_string(),
717            Self::DoublePrecision(r) => r.to_string(),
718            #[cfg(feature = "rust-decimal")]
719            Self::Numeric(d) => d.to_string(),
720            Self::Text(s) => s.clone(),
721            Self::Bytea(b) => {
722                use core::fmt::Write;
723                let mut s = String::with_capacity(2 + b.len() * 2);
724                s.push_str("\\x");
725                for byte in b {
726                    write!(s, "{byte:02x}").expect("writing to String cannot fail");
727                }
728                s
729            }
730            Self::Boolean(b) => b.to_string(),
731            #[cfg(feature = "uuid")]
732            Self::Uuid(uuid) => uuid.to_string(),
733            #[cfg(feature = "serde")]
734            Self::Json(json) => json.to_string(),
735            #[cfg(feature = "serde")]
736            Self::Jsonb(json) => json.to_string(),
737
738            // Date and time types
739            #[cfg(feature = "chrono")]
740            Self::Date(date) => date.to_string(),
741            #[cfg(feature = "chrono")]
742            Self::Time(time) => time.to_string(),
743            #[cfg(feature = "chrono")]
744            Self::Timestamp(ts) => ts.to_string(),
745            #[cfg(feature = "chrono")]
746            Self::TimestampTz(ts) => ts.to_string(),
747            #[cfg(feature = "chrono")]
748            Self::Interval(dur) => format!("{} seconds", dur.num_seconds()),
749
750            // Date and time types (time crate)
751            #[cfg(feature = "time")]
752            Self::TimeDate(date) => date.to_string(),
753            #[cfg(feature = "time")]
754            Self::TimeTime(time) => time.to_string(),
755            #[cfg(feature = "time")]
756            Self::TimeTimestamp(ts) => ts.to_string(),
757            #[cfg(feature = "time")]
758            Self::TimeTimestampTz(ts) => ts.to_string(),
759            #[cfg(feature = "time")]
760            Self::TimeInterval(dur) => format!("{} seconds", dur.whole_seconds()),
761
762            // Network address types
763            #[cfg(feature = "cidr")]
764            Self::Inet(net) => net.to_string(),
765            #[cfg(feature = "cidr")]
766            Self::Cidr(net) => net.to_string(),
767            #[cfg(feature = "cidr")]
768            Self::MacAddr(mac) => format!(
769                "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
770                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
771            ),
772            #[cfg(feature = "cidr")]
773            Self::MacAddr8(mac) => format!(
774                "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
775                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mac[6], mac[7]
776            ),
777
778            // Geometric types
779            #[cfg(feature = "geo-types")]
780            Self::Point(point) => format!("({},{})", point.x(), point.y()),
781            #[cfg(feature = "geo-types")]
782            Self::LineString(line) => {
783                let coords: Vec<String> = line
784                    .coords()
785                    .map(|coord| format!("({},{})", coord.x, coord.y))
786                    .collect();
787                format!("[{}]", coords.join(","))
788            }
789            #[cfg(feature = "geo-types")]
790            Self::Rect(rect) => {
791                format!(
792                    "(({},{}),({},{}))",
793                    rect.min().x,
794                    rect.min().y,
795                    rect.max().x,
796                    rect.max().y
797                )
798            }
799
800            // Bit string types
801            #[cfg(feature = "bit-vec")]
802            Self::BitVec(bv) => bv
803                .iter()
804                .map(|b| if b { '1' } else { '0' })
805                .collect::<String>(),
806
807            // Array types
808            Self::Array(arr) => {
809                let elements: Vec<String> = arr.iter().map(ToString::to_string).collect();
810                format!("{{{}}}", elements.join(","))
811            }
812
813            Self::Enum(enum_val) => enum_val.variant_name().to_string(),
814
815            Self::Null => String::new(),
816        };
817        write!(f, "{value}")
818    }
819}
820
821// Conversions from PostgresValue to OwnedPostgresValue
822impl<'a> From<PostgresValue<'a>> for OwnedPostgresValue {
823    fn from(value: PostgresValue<'a>) -> Self {
824        match value {
825            PostgresValue::Smallint(i) => Self::Smallint(i),
826            PostgresValue::Integer(i) => Self::Integer(i),
827            PostgresValue::Bigint(i) => Self::Bigint(i),
828            PostgresValue::Real(r) => Self::Real(r),
829            PostgresValue::DoublePrecision(r) => Self::DoublePrecision(r),
830            #[cfg(feature = "rust-decimal")]
831            PostgresValue::Numeric(d) => Self::Numeric(d),
832            PostgresValue::Text(cow) => Self::Text(cow.into_owned()),
833            PostgresValue::Bytea(cow) => Self::Bytea(cow.into_owned()),
834            PostgresValue::Boolean(b) => Self::Boolean(b),
835            #[cfg(feature = "uuid")]
836            PostgresValue::Uuid(uuid) => Self::Uuid(uuid),
837            #[cfg(feature = "serde")]
838            PostgresValue::Json(json) => Self::Json(json),
839            #[cfg(feature = "serde")]
840            PostgresValue::Jsonb(json) => Self::Jsonb(json),
841            PostgresValue::Enum(enum_val) => Self::Enum(enum_val),
842            PostgresValue::Null => Self::Null,
843            #[cfg(feature = "chrono")]
844            PostgresValue::Date(date) => Self::Date(date),
845            #[cfg(feature = "chrono")]
846            PostgresValue::Time(time) => Self::Time(time),
847            #[cfg(feature = "chrono")]
848            PostgresValue::Timestamp(ts) => Self::Timestamp(ts),
849            #[cfg(feature = "chrono")]
850            PostgresValue::TimestampTz(ts) => Self::TimestampTz(ts),
851            #[cfg(feature = "chrono")]
852            PostgresValue::Interval(dur) => Self::Interval(dur),
853            #[cfg(feature = "time")]
854            PostgresValue::TimeDate(v) => Self::TimeDate(v),
855            #[cfg(feature = "time")]
856            PostgresValue::TimeTime(v) => Self::TimeTime(v),
857            #[cfg(feature = "time")]
858            PostgresValue::TimeTimestamp(v) => Self::TimeTimestamp(v),
859            #[cfg(feature = "time")]
860            PostgresValue::TimeTimestampTz(v) => Self::TimeTimestampTz(v),
861            #[cfg(feature = "time")]
862            PostgresValue::TimeInterval(v) => Self::TimeInterval(v),
863            #[cfg(feature = "cidr")]
864            PostgresValue::Inet(net) => Self::Inet(net),
865            #[cfg(feature = "cidr")]
866            PostgresValue::Cidr(net) => Self::Cidr(net),
867            #[cfg(feature = "cidr")]
868            PostgresValue::MacAddr(mac) => Self::MacAddr(mac),
869            #[cfg(feature = "cidr")]
870            PostgresValue::MacAddr8(mac) => Self::MacAddr8(mac),
871            #[cfg(feature = "geo-types")]
872            PostgresValue::Point(point) => Self::Point(point),
873            #[cfg(feature = "geo-types")]
874            PostgresValue::LineString(line) => Self::LineString(line),
875            #[cfg(feature = "geo-types")]
876            PostgresValue::Rect(rect) => Self::Rect(rect),
877            #[cfg(feature = "bit-vec")]
878            PostgresValue::BitVec(bv) => Self::BitVec(bv),
879            PostgresValue::Array(arr) => {
880                let owned_arr = arr.into_iter().map(Self::from).collect();
881                Self::Array(owned_arr)
882            }
883        }
884    }
885}
886
887impl<'a> From<&PostgresValue<'a>> for OwnedPostgresValue {
888    fn from(value: &PostgresValue<'a>) -> Self {
889        match value {
890            PostgresValue::Smallint(i) => Self::Smallint(*i),
891            PostgresValue::Integer(i) => Self::Integer(*i),
892            PostgresValue::Bigint(i) => Self::Bigint(*i),
893            PostgresValue::Real(r) => Self::Real(*r),
894            PostgresValue::DoublePrecision(r) => Self::DoublePrecision(*r),
895            #[cfg(feature = "rust-decimal")]
896            PostgresValue::Numeric(d) => Self::Numeric(*d),
897            PostgresValue::Text(cow) => Self::Text(cow.clone().into_owned()),
898            PostgresValue::Bytea(cow) => Self::Bytea(cow.clone().into_owned()),
899            PostgresValue::Boolean(b) => Self::Boolean(*b),
900            #[cfg(feature = "uuid")]
901            PostgresValue::Uuid(uuid) => Self::Uuid(*uuid),
902            #[cfg(feature = "serde")]
903            PostgresValue::Json(json) => Self::Json(json.clone()),
904            #[cfg(feature = "serde")]
905            PostgresValue::Jsonb(json) => Self::Jsonb(json.clone()),
906            PostgresValue::Enum(enum_val) => Self::Enum(enum_val.clone()),
907            #[cfg(feature = "chrono")]
908            PostgresValue::Date(value) => Self::Date(*value),
909            #[cfg(feature = "chrono")]
910            PostgresValue::Time(value) => Self::Time(*value),
911            #[cfg(feature = "chrono")]
912            PostgresValue::Timestamp(value) => Self::Timestamp(*value),
913            #[cfg(feature = "chrono")]
914            PostgresValue::TimestampTz(value) => Self::TimestampTz(*value),
915            #[cfg(feature = "chrono")]
916            PostgresValue::Interval(value) => Self::Interval(*value),
917            #[cfg(feature = "time")]
918            PostgresValue::TimeDate(value) => Self::TimeDate(*value),
919            #[cfg(feature = "time")]
920            PostgresValue::TimeTime(value) => Self::TimeTime(*value),
921            #[cfg(feature = "time")]
922            PostgresValue::TimeTimestamp(value) => Self::TimeTimestamp(*value),
923            #[cfg(feature = "time")]
924            PostgresValue::TimeTimestampTz(value) => Self::TimeTimestampTz(*value),
925            #[cfg(feature = "time")]
926            PostgresValue::TimeInterval(value) => Self::TimeInterval(*value),
927            #[cfg(feature = "cidr")]
928            PostgresValue::Inet(value) => Self::Inet(*value),
929            #[cfg(feature = "cidr")]
930            PostgresValue::Cidr(value) => Self::Cidr(*value),
931            #[cfg(feature = "cidr")]
932            PostgresValue::MacAddr(value) => Self::MacAddr(*value),
933            #[cfg(feature = "cidr")]
934            PostgresValue::MacAddr8(value) => Self::MacAddr8(*value),
935            #[cfg(feature = "geo-types")]
936            PostgresValue::Point(value) => Self::Point(*value),
937            #[cfg(feature = "geo-types")]
938            PostgresValue::LineString(value) => Self::LineString(value.clone()),
939            #[cfg(feature = "geo-types")]
940            PostgresValue::Rect(value) => Self::Rect(*value),
941            #[cfg(feature = "bit-vec")]
942            PostgresValue::BitVec(value) => Self::BitVec(value.clone()),
943            PostgresValue::Array(arr) => {
944                let owned_arr = arr.iter().map(Self::from).collect();
945                Self::Array(owned_arr)
946            }
947            PostgresValue::Null => Self::Null,
948        }
949    }
950}
951
952// Conversions from OwnedPostgresValue to PostgresValue
953impl From<OwnedPostgresValue> for PostgresValue<'_> {
954    fn from(value: OwnedPostgresValue) -> Self {
955        match value {
956            OwnedPostgresValue::Smallint(i) => PostgresValue::Smallint(i),
957            OwnedPostgresValue::Integer(i) => PostgresValue::Integer(i),
958            OwnedPostgresValue::Bigint(i) => PostgresValue::Bigint(i),
959            OwnedPostgresValue::Real(r) => PostgresValue::Real(r),
960            OwnedPostgresValue::DoublePrecision(r) => PostgresValue::DoublePrecision(r),
961            #[cfg(feature = "rust-decimal")]
962            OwnedPostgresValue::Numeric(d) => PostgresValue::Numeric(d),
963            OwnedPostgresValue::Text(s) => PostgresValue::Text(Cow::Owned(s)),
964            OwnedPostgresValue::Bytea(b) => PostgresValue::Bytea(Cow::Owned(b)),
965            OwnedPostgresValue::Boolean(b) => PostgresValue::Boolean(b),
966            #[cfg(feature = "uuid")]
967            OwnedPostgresValue::Uuid(uuid) => PostgresValue::Uuid(uuid),
968            #[cfg(feature = "serde")]
969            OwnedPostgresValue::Json(json) => PostgresValue::Json(json),
970            #[cfg(feature = "serde")]
971            OwnedPostgresValue::Jsonb(json) => PostgresValue::Jsonb(json),
972
973            // Date and time types
974            #[cfg(feature = "chrono")]
975            OwnedPostgresValue::Date(date) => PostgresValue::Date(date),
976            #[cfg(feature = "chrono")]
977            OwnedPostgresValue::Time(time) => PostgresValue::Time(time),
978            #[cfg(feature = "chrono")]
979            OwnedPostgresValue::Timestamp(ts) => PostgresValue::Timestamp(ts),
980            #[cfg(feature = "chrono")]
981            OwnedPostgresValue::TimestampTz(ts) => PostgresValue::TimestampTz(ts),
982            #[cfg(feature = "chrono")]
983            OwnedPostgresValue::Interval(dur) => PostgresValue::Interval(dur),
984            #[cfg(feature = "time")]
985            OwnedPostgresValue::TimeDate(v) => PostgresValue::TimeDate(v),
986            #[cfg(feature = "time")]
987            OwnedPostgresValue::TimeTime(v) => PostgresValue::TimeTime(v),
988            #[cfg(feature = "time")]
989            OwnedPostgresValue::TimeTimestamp(v) => PostgresValue::TimeTimestamp(v),
990            #[cfg(feature = "time")]
991            OwnedPostgresValue::TimeTimestampTz(v) => PostgresValue::TimeTimestampTz(v),
992            #[cfg(feature = "time")]
993            OwnedPostgresValue::TimeInterval(v) => PostgresValue::TimeInterval(v),
994            #[cfg(feature = "cidr")]
995            OwnedPostgresValue::Inet(net) => PostgresValue::Inet(net),
996            #[cfg(feature = "cidr")]
997            OwnedPostgresValue::Cidr(net) => PostgresValue::Cidr(net),
998            #[cfg(feature = "cidr")]
999            OwnedPostgresValue::MacAddr(mac) => PostgresValue::MacAddr(mac),
1000            #[cfg(feature = "cidr")]
1001            OwnedPostgresValue::MacAddr8(mac) => PostgresValue::MacAddr8(mac),
1002            #[cfg(feature = "geo-types")]
1003            OwnedPostgresValue::Point(point) => PostgresValue::Point(point),
1004            #[cfg(feature = "geo-types")]
1005            OwnedPostgresValue::LineString(line) => PostgresValue::LineString(line),
1006            #[cfg(feature = "geo-types")]
1007            OwnedPostgresValue::Rect(rect) => PostgresValue::Rect(rect),
1008            #[cfg(feature = "bit-vec")]
1009            OwnedPostgresValue::BitVec(bv) => PostgresValue::BitVec(bv),
1010            OwnedPostgresValue::Array(arr) => {
1011                let postgres_arr = arr.into_iter().map(PostgresValue::from).collect();
1012                PostgresValue::Array(postgres_arr)
1013            }
1014
1015            OwnedPostgresValue::Enum(enum_val) => PostgresValue::Enum(enum_val),
1016
1017            OwnedPostgresValue::Null => PostgresValue::Null,
1018        }
1019    }
1020}
1021
1022impl<'a> From<&'a OwnedPostgresValue> for PostgresValue<'a> {
1023    fn from(value: &'a OwnedPostgresValue) -> Self {
1024        match value {
1025            OwnedPostgresValue::Smallint(i) => PostgresValue::Smallint(*i),
1026            OwnedPostgresValue::Integer(i) => PostgresValue::Integer(*i),
1027            OwnedPostgresValue::Bigint(i) => PostgresValue::Bigint(*i),
1028            OwnedPostgresValue::Real(r) => PostgresValue::Real(*r),
1029            OwnedPostgresValue::DoublePrecision(r) => PostgresValue::DoublePrecision(*r),
1030            #[cfg(feature = "rust-decimal")]
1031            OwnedPostgresValue::Numeric(d) => PostgresValue::Numeric(*d),
1032            OwnedPostgresValue::Text(s) => PostgresValue::Text(Cow::Borrowed(s)),
1033            OwnedPostgresValue::Bytea(b) => PostgresValue::Bytea(Cow::Borrowed(b)),
1034            OwnedPostgresValue::Boolean(b) => PostgresValue::Boolean(*b),
1035            #[cfg(feature = "uuid")]
1036            OwnedPostgresValue::Uuid(uuid) => PostgresValue::Uuid(*uuid),
1037            #[cfg(feature = "serde")]
1038            OwnedPostgresValue::Json(json) => PostgresValue::Json(json.clone()),
1039            #[cfg(feature = "serde")]
1040            OwnedPostgresValue::Jsonb(json) => PostgresValue::Jsonb(json.clone()),
1041            #[cfg(feature = "chrono")]
1042            OwnedPostgresValue::Date(value) => PostgresValue::Date(*value),
1043            #[cfg(feature = "chrono")]
1044            OwnedPostgresValue::Time(value) => PostgresValue::Time(*value),
1045            #[cfg(feature = "chrono")]
1046            OwnedPostgresValue::Timestamp(value) => PostgresValue::Timestamp(*value),
1047            #[cfg(feature = "chrono")]
1048            OwnedPostgresValue::TimestampTz(value) => PostgresValue::TimestampTz(*value),
1049            #[cfg(feature = "chrono")]
1050            OwnedPostgresValue::Interval(value) => PostgresValue::Interval(*value),
1051            #[cfg(feature = "time")]
1052            OwnedPostgresValue::TimeDate(value) => PostgresValue::TimeDate(*value),
1053            #[cfg(feature = "time")]
1054            OwnedPostgresValue::TimeTime(value) => PostgresValue::TimeTime(*value),
1055            #[cfg(feature = "time")]
1056            OwnedPostgresValue::TimeTimestamp(value) => PostgresValue::TimeTimestamp(*value),
1057            #[cfg(feature = "time")]
1058            OwnedPostgresValue::TimeTimestampTz(value) => PostgresValue::TimeTimestampTz(*value),
1059            #[cfg(feature = "time")]
1060            OwnedPostgresValue::TimeInterval(value) => PostgresValue::TimeInterval(*value),
1061            #[cfg(feature = "cidr")]
1062            OwnedPostgresValue::Inet(value) => PostgresValue::Inet(*value),
1063            #[cfg(feature = "cidr")]
1064            OwnedPostgresValue::Cidr(value) => PostgresValue::Cidr(*value),
1065            #[cfg(feature = "cidr")]
1066            OwnedPostgresValue::MacAddr(value) => PostgresValue::MacAddr(*value),
1067            #[cfg(feature = "cidr")]
1068            OwnedPostgresValue::MacAddr8(value) => PostgresValue::MacAddr8(*value),
1069            #[cfg(feature = "geo-types")]
1070            OwnedPostgresValue::Point(value) => PostgresValue::Point(*value),
1071            #[cfg(feature = "geo-types")]
1072            OwnedPostgresValue::LineString(value) => PostgresValue::LineString(value.clone()),
1073            #[cfg(feature = "geo-types")]
1074            OwnedPostgresValue::Rect(value) => PostgresValue::Rect(*value),
1075            #[cfg(feature = "bit-vec")]
1076            OwnedPostgresValue::BitVec(value) => PostgresValue::BitVec(value.clone()),
1077            OwnedPostgresValue::Array(values) => {
1078                PostgresValue::Array(values.iter().map(PostgresValue::from).collect())
1079            }
1080            OwnedPostgresValue::Enum(enum_val) => PostgresValue::Enum(enum_val.clone()),
1081            OwnedPostgresValue::Null => PostgresValue::Null,
1082        }
1083    }
1084}
1085
1086// Direct conversions from Rust types to OwnedPostgresValue
1087impl From<i16> for OwnedPostgresValue {
1088    fn from(value: i16) -> Self {
1089        Self::Smallint(value)
1090    }
1091}
1092
1093impl From<i32> for OwnedPostgresValue {
1094    fn from(value: i32) -> Self {
1095        Self::Integer(value)
1096    }
1097}
1098
1099impl From<i64> for OwnedPostgresValue {
1100    fn from(value: i64) -> Self {
1101        Self::Bigint(value)
1102    }
1103}
1104
1105impl From<f32> for OwnedPostgresValue {
1106    fn from(value: f32) -> Self {
1107        Self::Real(value)
1108    }
1109}
1110
1111impl From<f64> for OwnedPostgresValue {
1112    fn from(value: f64) -> Self {
1113        Self::DoublePrecision(value)
1114    }
1115}
1116
1117#[cfg(feature = "rust-decimal")]
1118impl From<Decimal> for OwnedPostgresValue {
1119    fn from(value: Decimal) -> Self {
1120        Self::Numeric(value)
1121    }
1122}
1123
1124#[cfg(feature = "rust-decimal")]
1125impl From<&Decimal> for OwnedPostgresValue {
1126    fn from(value: &Decimal) -> Self {
1127        Self::Numeric(*value)
1128    }
1129}
1130
1131impl From<&str> for OwnedPostgresValue {
1132    fn from(value: &str) -> Self {
1133        Self::Text(value.to_string())
1134    }
1135}
1136
1137impl From<&String> for OwnedPostgresValue {
1138    fn from(value: &String) -> Self {
1139        Self::Text(value.clone())
1140    }
1141}
1142
1143impl From<Box<str>> for OwnedPostgresValue {
1144    fn from(value: Box<str>) -> Self {
1145        Self::Text(value.into())
1146    }
1147}
1148
1149impl From<&Box<str>> for OwnedPostgresValue {
1150    fn from(value: &Box<str>) -> Self {
1151        Self::Text(value.as_ref().to_string())
1152    }
1153}
1154
1155impl From<Rc<str>> for OwnedPostgresValue {
1156    fn from(value: Rc<str>) -> Self {
1157        Self::Text(value.as_ref().to_string())
1158    }
1159}
1160
1161impl From<&Rc<str>> for OwnedPostgresValue {
1162    fn from(value: &Rc<str>) -> Self {
1163        Self::Text(value.as_ref().to_string())
1164    }
1165}
1166
1167impl From<Arc<str>> for OwnedPostgresValue {
1168    fn from(value: Arc<str>) -> Self {
1169        Self::Text(value.as_ref().to_string())
1170    }
1171}
1172
1173impl From<&Arc<str>> for OwnedPostgresValue {
1174    fn from(value: &Arc<str>) -> Self {
1175        Self::Text(value.as_ref().to_string())
1176    }
1177}
1178
1179impl From<String> for OwnedPostgresValue {
1180    fn from(value: String) -> Self {
1181        Self::Text(value)
1182    }
1183}
1184
1185impl From<Box<String>> for OwnedPostgresValue {
1186    fn from(value: Box<String>) -> Self {
1187        Self::Text(*value)
1188    }
1189}
1190
1191impl From<&Box<String>> for OwnedPostgresValue {
1192    fn from(value: &Box<String>) -> Self {
1193        Self::Text(value.as_ref().clone())
1194    }
1195}
1196
1197impl From<Rc<String>> for OwnedPostgresValue {
1198    fn from(value: Rc<String>) -> Self {
1199        Self::Text(value.as_ref().clone())
1200    }
1201}
1202
1203impl From<&Rc<String>> for OwnedPostgresValue {
1204    fn from(value: &Rc<String>) -> Self {
1205        Self::Text(value.as_ref().clone())
1206    }
1207}
1208
1209impl From<Arc<String>> for OwnedPostgresValue {
1210    fn from(value: Arc<String>) -> Self {
1211        Self::Text(value.as_ref().clone())
1212    }
1213}
1214
1215impl From<&Arc<String>> for OwnedPostgresValue {
1216    fn from(value: &Arc<String>) -> Self {
1217        Self::Text(value.as_ref().clone())
1218    }
1219}
1220
1221impl From<Vec<u8>> for OwnedPostgresValue {
1222    fn from(value: Vec<u8>) -> Self {
1223        Self::Bytea(value)
1224    }
1225}
1226
1227impl From<Box<Vec<u8>>> for OwnedPostgresValue {
1228    fn from(value: Box<Vec<u8>>) -> Self {
1229        Self::Bytea(*value)
1230    }
1231}
1232
1233impl From<&Box<Vec<u8>>> for OwnedPostgresValue {
1234    fn from(value: &Box<Vec<u8>>) -> Self {
1235        Self::Bytea(value.as_ref().clone())
1236    }
1237}
1238
1239impl From<Rc<Vec<u8>>> for OwnedPostgresValue {
1240    fn from(value: Rc<Vec<u8>>) -> Self {
1241        Self::Bytea(value.as_ref().clone())
1242    }
1243}
1244
1245impl From<&Rc<Vec<u8>>> for OwnedPostgresValue {
1246    fn from(value: &Rc<Vec<u8>>) -> Self {
1247        Self::Bytea(value.as_ref().clone())
1248    }
1249}
1250
1251impl From<Arc<Vec<u8>>> for OwnedPostgresValue {
1252    fn from(value: Arc<Vec<u8>>) -> Self {
1253        Self::Bytea(value.as_ref().clone())
1254    }
1255}
1256
1257impl From<&Arc<Vec<u8>>> for OwnedPostgresValue {
1258    fn from(value: &Arc<Vec<u8>>) -> Self {
1259        Self::Bytea(value.as_ref().clone())
1260    }
1261}
1262
1263impl From<bool> for OwnedPostgresValue {
1264    fn from(value: bool) -> Self {
1265        Self::Boolean(value)
1266    }
1267}
1268
1269#[cfg(feature = "uuid")]
1270impl From<Uuid> for OwnedPostgresValue {
1271    fn from(value: Uuid) -> Self {
1272        Self::Uuid(value)
1273    }
1274}
1275
1276#[cfg(feature = "serde")]
1277impl From<serde_json::Value> for OwnedPostgresValue {
1278    fn from(value: serde_json::Value) -> Self {
1279        Self::Json(value)
1280    }
1281}
1282
1283#[cfg(feature = "time")]
1284impl From<TimeDate> for OwnedPostgresValue {
1285    fn from(value: TimeDate) -> Self {
1286        Self::TimeDate(value)
1287    }
1288}
1289
1290#[cfg(feature = "time")]
1291impl From<TimeTime> for OwnedPostgresValue {
1292    fn from(value: TimeTime) -> Self {
1293        Self::TimeTime(value)
1294    }
1295}
1296
1297#[cfg(feature = "time")]
1298impl From<PrimitiveDateTime> for OwnedPostgresValue {
1299    fn from(value: PrimitiveDateTime) -> Self {
1300        Self::TimeTimestamp(value)
1301    }
1302}
1303
1304#[cfg(feature = "time")]
1305impl From<OffsetDateTime> for OwnedPostgresValue {
1306    fn from(value: OffsetDateTime) -> Self {
1307        Self::TimeTimestampTz(value)
1308    }
1309}
1310
1311#[cfg(feature = "time")]
1312impl From<TimeDuration> for OwnedPostgresValue {
1313    fn from(value: TimeDuration) -> Self {
1314        Self::TimeInterval(value)
1315    }
1316}
1317
1318#[cfg(feature = "arrayvec")]
1319impl<const N: usize> From<arrayvec::ArrayString<N>> for OwnedPostgresValue {
1320    fn from(value: arrayvec::ArrayString<N>) -> Self {
1321        Self::Text(value.to_string())
1322    }
1323}
1324
1325#[cfg(feature = "compact-str")]
1326impl From<compact_str::CompactString> for OwnedPostgresValue {
1327    fn from(value: compact_str::CompactString) -> Self {
1328        Self::Text(value.to_string())
1329    }
1330}
1331
1332#[cfg(feature = "arrayvec")]
1333impl<const N: usize> From<arrayvec::ArrayVec<u8, N>> for OwnedPostgresValue {
1334    fn from(value: arrayvec::ArrayVec<u8, N>) -> Self {
1335        Self::Bytea(value.to_vec())
1336    }
1337}
1338
1339#[cfg(feature = "bytes")]
1340impl From<bytes::Bytes> for OwnedPostgresValue {
1341    fn from(value: bytes::Bytes) -> Self {
1342        Self::Bytea(value.to_vec())
1343    }
1344}
1345
1346#[cfg(feature = "bytes")]
1347impl From<bytes::BytesMut> for OwnedPostgresValue {
1348    fn from(value: bytes::BytesMut) -> Self {
1349        Self::Bytea(value.to_vec())
1350    }
1351}
1352
1353#[cfg(feature = "smallvec")]
1354impl<const N: usize> From<smallvec::SmallVec<[u8; N]>> for OwnedPostgresValue {
1355    fn from(value: smallvec::SmallVec<[u8; N]>) -> Self {
1356        Self::Bytea(value.into_vec())
1357    }
1358}
1359
1360// TryFrom conversions back to Rust types
1361impl TryFrom<OwnedPostgresValue> for i16 {
1362    type Error = DrizzleError;
1363
1364    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1365        match value {
1366            OwnedPostgresValue::Smallint(i) => Ok(i),
1367            OwnedPostgresValue::Integer(i) => Ok(i.try_into()?),
1368            OwnedPostgresValue::Bigint(i) => Ok(i.try_into()?),
1369            _ => Err(DrizzleError::ConversionError(
1370                format!("Cannot convert {value:?} to i16").into(),
1371            )),
1372        }
1373    }
1374}
1375
1376impl TryFrom<OwnedPostgresValue> for i32 {
1377    type Error = DrizzleError;
1378
1379    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1380        match value {
1381            OwnedPostgresValue::Smallint(i) => Ok(i.into()),
1382            OwnedPostgresValue::Integer(i) => Ok(i),
1383            OwnedPostgresValue::Bigint(i) => Ok(i.try_into()?),
1384            _ => Err(DrizzleError::ConversionError(
1385                format!("Cannot convert {value:?} to i32").into(),
1386            )),
1387        }
1388    }
1389}
1390
1391impl TryFrom<OwnedPostgresValue> for i64 {
1392    type Error = DrizzleError;
1393
1394    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1395        match value {
1396            OwnedPostgresValue::Smallint(i) => Ok(i.into()),
1397            OwnedPostgresValue::Integer(i) => Ok(i.into()),
1398            OwnedPostgresValue::Bigint(i) => Ok(i),
1399            _ => Err(DrizzleError::ConversionError(
1400                format!("Cannot convert {value:?} to i64").into(),
1401            )),
1402        }
1403    }
1404}
1405
1406impl TryFrom<OwnedPostgresValue> for f32 {
1407    type Error = DrizzleError;
1408
1409    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1410        fn parse_float<N: core::fmt::Display>(value: N) -> Result<f32, DrizzleError> {
1411            format!("{value}").parse::<f32>().map_err(|e| {
1412                DrizzleError::ConversionError(format!("Cannot convert to f32: {e}").into())
1413            })
1414        }
1415        match value {
1416            OwnedPostgresValue::Real(r) => Ok(r),
1417            OwnedPostgresValue::DoublePrecision(r) => parse_float(r),
1418            OwnedPostgresValue::Smallint(i) => Ok(Self::from(i)),
1419            OwnedPostgresValue::Integer(i) => parse_float(i),
1420            OwnedPostgresValue::Bigint(i) => parse_float(i),
1421            _ => Err(DrizzleError::ConversionError(
1422                format!("Cannot convert {value:?} to f32").into(),
1423            )),
1424        }
1425    }
1426}
1427
1428impl TryFrom<OwnedPostgresValue> for f64 {
1429    type Error = DrizzleError;
1430
1431    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1432        fn parse_double<N: core::fmt::Display>(value: N) -> Result<f64, DrizzleError> {
1433            format!("{value}").parse::<f64>().map_err(|e| {
1434                DrizzleError::ConversionError(format!("Cannot convert to f64: {e}").into())
1435            })
1436        }
1437        match value {
1438            OwnedPostgresValue::Real(r) => Ok(Self::from(r)),
1439            OwnedPostgresValue::DoublePrecision(r) => Ok(r),
1440            OwnedPostgresValue::Smallint(i) => Ok(Self::from(i)),
1441            OwnedPostgresValue::Integer(i) => Ok(Self::from(i)),
1442            OwnedPostgresValue::Bigint(i) => parse_double(i),
1443            _ => Err(DrizzleError::ConversionError(
1444                format!("Cannot convert {value:?} to f64").into(),
1445            )),
1446        }
1447    }
1448}
1449
1450impl TryFrom<OwnedPostgresValue> for String {
1451    type Error = DrizzleError;
1452
1453    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1454        match value {
1455            OwnedPostgresValue::Text(s) => Ok(s),
1456            _ => Err(DrizzleError::ConversionError(
1457                format!("Cannot convert {value:?} to String").into(),
1458            )),
1459        }
1460    }
1461}
1462
1463impl TryFrom<OwnedPostgresValue> for Box<String> {
1464    type Error = DrizzleError;
1465
1466    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1467        String::try_from(value).map(Self::new)
1468    }
1469}
1470
1471impl TryFrom<OwnedPostgresValue> for Rc<String> {
1472    type Error = DrizzleError;
1473
1474    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1475        String::try_from(value).map(Self::new)
1476    }
1477}
1478
1479impl TryFrom<OwnedPostgresValue> for Arc<String> {
1480    type Error = DrizzleError;
1481
1482    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1483        String::try_from(value).map(Self::new)
1484    }
1485}
1486
1487impl TryFrom<OwnedPostgresValue> for Box<str> {
1488    type Error = DrizzleError;
1489
1490    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1491        match value {
1492            OwnedPostgresValue::Text(s) => Ok(s.into_boxed_str()),
1493            _ => Err(DrizzleError::ConversionError(
1494                format!("Cannot convert {value:?} to Box<str>").into(),
1495            )),
1496        }
1497    }
1498}
1499
1500impl TryFrom<OwnedPostgresValue> for Rc<str> {
1501    type Error = DrizzleError;
1502
1503    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1504        match value {
1505            OwnedPostgresValue::Text(s) => Ok(Self::from(s)),
1506            _ => Err(DrizzleError::ConversionError(
1507                format!("Cannot convert {value:?} to Rc<str>").into(),
1508            )),
1509        }
1510    }
1511}
1512
1513impl TryFrom<OwnedPostgresValue> for Arc<str> {
1514    type Error = DrizzleError;
1515
1516    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1517        match value {
1518            OwnedPostgresValue::Text(s) => Ok(Self::from(s)),
1519            _ => Err(DrizzleError::ConversionError(
1520                format!("Cannot convert {value:?} to Arc<str>").into(),
1521            )),
1522        }
1523    }
1524}
1525
1526#[cfg(feature = "compact-str")]
1527impl TryFrom<OwnedPostgresValue> for compact_str::CompactString {
1528    type Error = DrizzleError;
1529
1530    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1531        String::try_from(value).map(Self::new)
1532    }
1533}
1534
1535impl TryFrom<OwnedPostgresValue> for Vec<u8> {
1536    type Error = DrizzleError;
1537
1538    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1539        match value {
1540            OwnedPostgresValue::Bytea(b) => Ok(b),
1541            _ => Err(DrizzleError::ConversionError(
1542                format!("Cannot convert {value:?} to Vec<u8>").into(),
1543            )),
1544        }
1545    }
1546}
1547
1548impl TryFrom<OwnedPostgresValue> for Box<Vec<u8>> {
1549    type Error = DrizzleError;
1550
1551    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1552        Vec::<u8>::try_from(value).map(Self::new)
1553    }
1554}
1555
1556impl TryFrom<OwnedPostgresValue> for Rc<Vec<u8>> {
1557    type Error = DrizzleError;
1558
1559    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1560        Vec::<u8>::try_from(value).map(Self::new)
1561    }
1562}
1563
1564impl TryFrom<OwnedPostgresValue> for Arc<Vec<u8>> {
1565    type Error = DrizzleError;
1566
1567    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1568        Vec::<u8>::try_from(value).map(Self::new)
1569    }
1570}
1571
1572#[cfg(feature = "bytes")]
1573impl TryFrom<OwnedPostgresValue> for bytes::Bytes {
1574    type Error = DrizzleError;
1575
1576    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1577        Vec::<u8>::try_from(value).map(Self::from)
1578    }
1579}
1580
1581#[cfg(feature = "bytes")]
1582impl TryFrom<OwnedPostgresValue> for bytes::BytesMut {
1583    type Error = DrizzleError;
1584
1585    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1586        Vec::<u8>::try_from(value).map(|v| Self::from(v.as_slice()))
1587    }
1588}
1589
1590#[cfg(feature = "smallvec")]
1591impl<const N: usize> TryFrom<OwnedPostgresValue> for smallvec::SmallVec<[u8; N]> {
1592    type Error = DrizzleError;
1593
1594    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1595        Vec::<u8>::try_from(value).map(|v| {
1596            let mut out = Self::new();
1597            out.extend_from_slice(&v);
1598            out
1599        })
1600    }
1601}
1602
1603impl TryFrom<OwnedPostgresValue> for bool {
1604    type Error = DrizzleError;
1605
1606    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1607        match value {
1608            OwnedPostgresValue::Boolean(b) => Ok(b),
1609            _ => Err(DrizzleError::ConversionError(
1610                format!("Cannot convert {value:?} to bool").into(),
1611            )),
1612        }
1613    }
1614}
1615
1616#[cfg(feature = "uuid")]
1617impl TryFrom<OwnedPostgresValue> for Uuid {
1618    type Error = DrizzleError;
1619
1620    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1621        match value {
1622            OwnedPostgresValue::Uuid(uuid) => Ok(uuid),
1623            OwnedPostgresValue::Text(s) => Self::parse_str(&s).map_err(|e| {
1624                DrizzleError::ConversionError(format!("Failed to parse UUID: {e}").into())
1625            }),
1626            _ => Err(DrizzleError::ConversionError(
1627                format!("Cannot convert {value:?} to UUID").into(),
1628            )),
1629        }
1630    }
1631}
1632
1633#[cfg(feature = "serde")]
1634impl TryFrom<OwnedPostgresValue> for serde_json::Value {
1635    type Error = DrizzleError;
1636
1637    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1638        match value {
1639            OwnedPostgresValue::Json(json) | OwnedPostgresValue::Jsonb(json) => Ok(json),
1640            OwnedPostgresValue::Text(s) => serde_json::from_str(&s).map_err(|e| {
1641                DrizzleError::ConversionError(format!("Failed to parse JSON: {e}").into())
1642            }),
1643            _ => Err(DrizzleError::ConversionError(
1644                format!("Cannot convert {value:?} to JSON").into(),
1645            )),
1646        }
1647    }
1648}
1649
1650#[cfg(feature = "arrayvec")]
1651impl<const N: usize> TryFrom<OwnedPostgresValue> for arrayvec::ArrayString<N> {
1652    type Error = DrizzleError;
1653
1654    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1655        match value {
1656            OwnedPostgresValue::Text(s) => Self::from(&s).map_err(|_| {
1657                DrizzleError::ConversionError(
1658                    format!("Text length {} exceeds ArrayString capacity {}", s.len(), N).into(),
1659                )
1660            }),
1661            _ => Err(DrizzleError::ConversionError(
1662                format!("Cannot convert {value:?} to ArrayString").into(),
1663            )),
1664        }
1665    }
1666}
1667
1668#[cfg(feature = "arrayvec")]
1669impl<const N: usize> TryFrom<OwnedPostgresValue> for arrayvec::ArrayVec<u8, N> {
1670    type Error = DrizzleError;
1671
1672    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1673        match value {
1674            OwnedPostgresValue::Bytea(bytes) => Self::try_from(bytes.as_slice()).map_err(|_| {
1675                DrizzleError::ConversionError(
1676                    format!(
1677                        "Bytea length {} exceeds ArrayVec capacity {}",
1678                        bytes.len(),
1679                        N
1680                    )
1681                    .into(),
1682                )
1683            }),
1684            _ => Err(DrizzleError::ConversionError(
1685                format!("Cannot convert {value:?} to ArrayVec<u8>").into(),
1686            )),
1687        }
1688    }
1689}
1690
1691#[cfg(feature = "time")]
1692impl TryFrom<OwnedPostgresValue> for TimeDate {
1693    type Error = DrizzleError;
1694
1695    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1696        match value {
1697            OwnedPostgresValue::TimeDate(date) => Ok(date),
1698            OwnedPostgresValue::TimeTimestamp(ts) => Ok(ts.date()),
1699            OwnedPostgresValue::TimeTimestampTz(ts) => Ok(ts.date()),
1700            _ => Err(DrizzleError::ConversionError(
1701                format!("Cannot convert {value:?} to time::Date").into(),
1702            )),
1703        }
1704    }
1705}
1706
1707#[cfg(feature = "time")]
1708impl TryFrom<OwnedPostgresValue> for TimeTime {
1709    type Error = DrizzleError;
1710
1711    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1712        match value {
1713            OwnedPostgresValue::TimeTime(time) => Ok(time),
1714            OwnedPostgresValue::TimeTimestamp(ts) => Ok(ts.time()),
1715            OwnedPostgresValue::TimeTimestampTz(ts) => Ok(ts.time()),
1716            _ => Err(DrizzleError::ConversionError(
1717                format!("Cannot convert {value:?} to time::Time").into(),
1718            )),
1719        }
1720    }
1721}
1722
1723#[cfg(feature = "time")]
1724impl TryFrom<OwnedPostgresValue> for PrimitiveDateTime {
1725    type Error = DrizzleError;
1726
1727    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1728        match value {
1729            OwnedPostgresValue::TimeTimestamp(ts) => Ok(ts),
1730            _ => Err(DrizzleError::ConversionError(
1731                format!("Cannot convert {value:?} to time::PrimitiveDateTime").into(),
1732            )),
1733        }
1734    }
1735}
1736
1737#[cfg(feature = "time")]
1738impl TryFrom<OwnedPostgresValue> for OffsetDateTime {
1739    type Error = DrizzleError;
1740
1741    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1742        match value {
1743            OwnedPostgresValue::TimeTimestampTz(ts) => Ok(ts),
1744            _ => Err(DrizzleError::ConversionError(
1745                format!("Cannot convert {value:?} to time::OffsetDateTime").into(),
1746            )),
1747        }
1748    }
1749}
1750
1751#[cfg(feature = "time")]
1752impl TryFrom<OwnedPostgresValue> for TimeDuration {
1753    type Error = DrizzleError;
1754
1755    fn try_from(value: OwnedPostgresValue) -> Result<Self, Self::Error> {
1756        match value {
1757            OwnedPostgresValue::TimeInterval(dur) => Ok(dur),
1758            _ => Err(DrizzleError::ConversionError(
1759                format!("Cannot convert {value:?} to time::Duration").into(),
1760            )),
1761        }
1762    }
1763}