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