mod enum_type;
mod from_sql_row;
mod oid;
mod standard_types;
mod binary;
mod bool;
mod char;
mod collections;
#[cfg(feature = "time")]
mod datetime;
#[cfg(feature = "json")]
mod json_type;
mod nullable;
mod numbers;
mod text;
#[cfg(feature = "uuid")]
mod uuid_type;
#[cfg(feature = "json")]
pub use json_type::{Json, Jsonb};
#[cfg(feature = "decimal")]
mod numeric_type;
mod point_type;
pub use point_type::Point;
mod network_type;
pub use enum_type::*;
pub use network_type::{Cidr, Inet};
use crate::protocol::FieldDescription;
use crate::ElefantClientError;
pub use from_sql_row::*;
pub use oid::*;
use std::error::Error;
pub trait FromSqlBase<'a>: Sized {
fn accepts(field: &FieldDescription) -> bool {
Self::accepts_postgres_type(field.data_type_oid)
}
fn accepts_postgres_type(oid: i32) -> bool;
fn accepts_with_registry(field: &FieldDescription, _registry: &EnumTypeRegistry) -> bool {
Self::accepts(field)
}
fn from_null(field: &FieldDescription) -> Result<Self, ElefantClientError> {
Err(ElefantClientError::UnexpectedNullValue {
postgres_field: field.clone(),
})
}
}
pub trait FromSqlBinary<'a>: FromSqlBase<'a> {
fn from_sql_binary(
raw: &'a [u8],
field: &FieldDescription,
) -> Result<Self, Box<dyn Error + Sync + Send>>;
}
pub trait FromSqlText<'a>: FromSqlBase<'a> {
fn from_sql_text(
raw: &'a str,
field: &FieldDescription,
) -> Result<Self, Box<dyn Error + Sync + Send>>;
}
pub trait FromSql<'a>: FromSqlBinary<'a> + FromSqlText<'a> {}
impl<'a, T> FromSql<'a> for T where T: FromSqlBinary<'a> + FromSqlText<'a> {}
pub trait FromSqlOwned: for<'owned> FromSql<'owned> {}
impl<T> FromSqlOwned for T where T: for<'a> FromSql<'a> {}
pub trait FromSqlBinaryOwned: for<'owned> FromSqlBinary<'owned> {}
impl<T> FromSqlBinaryOwned for T where T: for<'a> FromSqlBinary<'a> {}
pub trait FromSqlTextOwned: for<'owned> FromSqlText<'owned> {}
impl<T> FromSqlTextOwned for T where T: for<'a> FromSqlText<'a> {}
pub trait ToSql {
fn to_sql_binary(
&self,
target_buffer: &mut Vec<u8>,
) -> Result<(), Box<dyn Error + Sync + Send>>;
fn is_null(&self) -> bool {
false
}
}
pub trait PostgresNamedType {
const PG_NAME: &'static str;
}
pub trait DomainType {
type Inner: for<'owned> FromSql<'owned>;
fn from_inner(inner: Self::Inner) -> Self;
fn accepts(field: &FieldDescription) -> bool {
Self::accepts_postgres_type(field.data_type_oid)
}
fn accepts_postgres_type(oid: i32) -> bool;
}
#[macro_export]
macro_rules! impl_from_sql_for_domain_type {
($typ: ty) => {
impl<'a> FromSqlBase<'a> for $typ {
fn accepts(field: &FieldDescription) -> bool {
<Self as DomainType>::accepts(field)
}
fn accepts_postgres_type(oid: i32) -> bool {
<Self as DomainType>::accepts_postgres_type(oid)
}
}
impl<'a> FromSqlBinary<'a> for $typ {
fn from_sql_binary(
raw: &'a [u8],
field: &FieldDescription,
) -> Result<Self, Box<dyn Error + Sync + Send>> {
let inner = <Self as DomainType>::Inner::from_sql_binary(raw, field)?;
Ok(Self::from_inner(inner))
}
}
impl<'a> FromSqlText<'a> for $typ {
fn from_sql_text(
raw: &'a str,
field: &FieldDescription,
) -> Result<Self, Box<dyn Error + Sync + Send>> {
let inner = <Self as DomainType>::Inner::from_sql_text(raw, field)?;
Ok(Self::from_inner(inner))
}
}
};
}
pub struct PostgresType {
pub(crate) oid: i32,
name: &'static str,
element: Option<&'static PostgresType>,
is_array: bool,
array_delimiter: char,
}
impl PostgresType {
fn inner_most(&self) -> &PostgresType {
match self.element {
Some(element) => element.inner_most(),
None => self,
}
}
}