xxai_postgres_types/
special.rs1use bytes::BytesMut;
2use postgres_protocol::types;
3use std::error::Error;
4use std::{i32, i64};
5
6use crate::{FromSql, IsNull, ToSql, Type};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum Date<T> {
11 PosInfinity,
13 NegInfinity,
15 Value(T),
17}
18
19impl<'a, T: FromSql<'a>> FromSql<'a> for Date<T> {
20 fn from_sql(ty: &Type, raw: &'a [u8]) -> Result<Self, Box<dyn Error + Sync + Send>> {
21 match types::date_from_sql(raw)? {
22 i32::MAX => Ok(Date::PosInfinity),
23 i32::MIN => Ok(Date::NegInfinity),
24 _ => T::from_sql(ty, raw).map(Date::Value),
25 }
26 }
27
28 fn accepts(ty: &Type) -> bool {
29 *ty == Type::DATE && T::accepts(ty)
30 }
31}
32
33impl<T: ToSql> ToSql for Date<T> {
34 fn to_sql(
35 &self,
36 ty: &Type,
37 out: &mut BytesMut,
38 ) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
39 let value = match *self {
40 Date::PosInfinity => i32::MAX,
41 Date::NegInfinity => i32::MIN,
42 Date::Value(ref v) => return v.to_sql(ty, out),
43 };
44
45 types::date_to_sql(value, out);
46 Ok(IsNull::No)
47 }
48
49 fn accepts(ty: &Type) -> bool {
50 *ty == Type::DATE && T::accepts(ty)
51 }
52
53 to_sql_checked!();
54}
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq)]
59pub enum Timestamp<T> {
60 PosInfinity,
62 NegInfinity,
64 Value(T),
66}
67
68impl<'a, T: FromSql<'a>> FromSql<'a> for Timestamp<T> {
69 fn from_sql(ty: &Type, raw: &'a [u8]) -> Result<Self, Box<dyn Error + Sync + Send>> {
70 match types::timestamp_from_sql(raw)? {
71 i64::MAX => Ok(Timestamp::PosInfinity),
72 i64::MIN => Ok(Timestamp::NegInfinity),
73 _ => T::from_sql(ty, raw).map(Timestamp::Value),
74 }
75 }
76
77 fn accepts(ty: &Type) -> bool {
78 matches!(*ty, Type::TIMESTAMP | Type::TIMESTAMPTZ if T::accepts(ty))
79 }
80}
81
82impl<T: ToSql> ToSql for Timestamp<T> {
83 fn to_sql(
84 &self,
85 ty: &Type,
86 out: &mut BytesMut,
87 ) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
88 let value = match *self {
89 Timestamp::PosInfinity => i64::MAX,
90 Timestamp::NegInfinity => i64::MIN,
91 Timestamp::Value(ref v) => return v.to_sql(ty, out),
92 };
93
94 types::timestamp_to_sql(value, out);
95 Ok(IsNull::No)
96 }
97
98 fn accepts(ty: &Type) -> bool {
99 matches!(*ty, Type::TIMESTAMP | Type::TIMESTAMPTZ if T::accepts(ty))
100 }
101
102 to_sql_checked!();
103}