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