elefant_client/types/
mod.rs1mod enum_type;
2mod from_sql_row;
3mod oid;
4mod standard_types;
5
6mod binary;
8mod bool;
9mod char;
10mod collections;
11#[cfg(feature = "time")]
12mod datetime;
13#[cfg(feature = "json")]
14mod json_type;
15mod nullable;
16mod numbers;
17mod text;
18#[cfg(feature = "uuid")]
19mod uuid_type;
20#[cfg(feature = "json")]
21pub use json_type::{Json, Jsonb};
22#[cfg(feature = "decimal")]
23mod numeric_type;
24mod point_type;
25pub use point_type::Point;
26mod network_type;
27pub use enum_type::*;
28pub use network_type::{Cidr, Inet};
29
30use crate::protocol::FieldDescription;
31use crate::ElefantClientError;
32pub use from_sql_row::*;
33pub use oid::*;
34use std::error::Error;
35
36pub trait FromSqlBase<'a>: Sized {
38 fn accepts(field: &FieldDescription) -> bool {
39 Self::accepts_postgres_type(field.data_type_oid)
40 }
41
42 fn accepts_postgres_type(oid: i32) -> bool;
43
44 fn accepts_with_registry(field: &FieldDescription, _registry: &EnumTypeRegistry) -> bool {
48 Self::accepts(field)
49 }
50
51 fn from_null(field: &FieldDescription) -> Result<Self, ElefantClientError> {
52 Err(ElefantClientError::UnexpectedNullValue {
53 postgres_field: field.clone(),
54 })
55 }
56}
57
58pub trait FromSqlBinary<'a>: FromSqlBase<'a> {
60 fn from_sql_binary(
61 raw: &'a [u8],
62 field: &FieldDescription,
63 ) -> Result<Self, Box<dyn Error + Sync + Send>>;
64}
65
66pub trait FromSqlText<'a>: FromSqlBase<'a> {
68 fn from_sql_text(
69 raw: &'a str,
70 field: &FieldDescription,
71 ) -> Result<Self, Box<dyn Error + Sync + Send>>;
72}
73
74pub trait FromSql<'a>: FromSqlBinary<'a> + FromSqlText<'a> {}
77
78impl<'a, T> FromSql<'a> for T where T: FromSqlBinary<'a> + FromSqlText<'a> {}
80
81pub trait FromSqlOwned: for<'owned> FromSql<'owned> {}
84
85impl<T> FromSqlOwned for T where T: for<'a> FromSql<'a> {}
86
87pub trait FromSqlBinaryOwned: for<'owned> FromSqlBinary<'owned> {}
89
90impl<T> FromSqlBinaryOwned for T where T: for<'a> FromSqlBinary<'a> {}
91
92pub trait FromSqlTextOwned: for<'owned> FromSqlText<'owned> {}
94
95impl<T> FromSqlTextOwned for T where T: for<'a> FromSqlText<'a> {}
96
97pub trait ToSql {
98 fn to_sql_binary(
99 &self,
100 target_buffer: &mut Vec<u8>,
101 ) -> Result<(), Box<dyn Error + Sync + Send>>;
102 fn is_null(&self) -> bool {
103 false
104 }
105}
106
107pub trait PostgresNamedType {
108 const PG_NAME: &'static str;
109}
110
111pub trait DomainType {
112 type Inner: for<'owned> FromSql<'owned>;
113
114 fn from_inner(inner: Self::Inner) -> Self;
115
116 fn accepts(field: &FieldDescription) -> bool {
117 Self::accepts_postgres_type(field.data_type_oid)
118 }
119
120 fn accepts_postgres_type(oid: i32) -> bool;
121}
122
123#[macro_export]
124macro_rules! impl_from_sql_for_domain_type {
125 ($typ: ty) => {
126 impl<'a> FromSqlBase<'a> for $typ {
127 fn accepts(field: &FieldDescription) -> bool {
128 <Self as DomainType>::accepts(field)
129 }
130
131 fn accepts_postgres_type(oid: i32) -> bool {
132 <Self as DomainType>::accepts_postgres_type(oid)
133 }
134 }
135
136 impl<'a> FromSqlBinary<'a> for $typ {
137 fn from_sql_binary(
138 raw: &'a [u8],
139 field: &FieldDescription,
140 ) -> Result<Self, Box<dyn Error + Sync + Send>> {
141 let inner = <Self as DomainType>::Inner::from_sql_binary(raw, field)?;
142 Ok(Self::from_inner(inner))
143 }
144 }
145
146 impl<'a> FromSqlText<'a> for $typ {
147 fn from_sql_text(
148 raw: &'a str,
149 field: &FieldDescription,
150 ) -> Result<Self, Box<dyn Error + Sync + Send>> {
151 let inner = <Self as DomainType>::Inner::from_sql_text(raw, field)?;
152 Ok(Self::from_inner(inner))
153 }
154 }
155 };
156}
157
158pub struct PostgresType {
159 pub(crate) oid: i32,
160 name: &'static str,
161 element: Option<&'static PostgresType>,
163 is_array: bool,
165
166 array_delimiter: char,
167}
168
169impl PostgresType {
170 fn inner_most(&self) -> &PostgresType {
171 match self.element {
172 Some(element) => element.inner_most(),
173 None => self,
174 }
175 }
176}