use std::{collections::HashMap, net::IpAddr, time::SystemTime};
#[cfg(feature = "with-serde_json-1")]
pub use tokio_postgres::types::Json;
pub trait FromSqlTyped<'a, T> {}
pub trait QueryParamTyped<T> {}
pub trait QueryRowTyped<T> {}
pub trait QueryNullableRowTyped<T> {}
pub trait QueryMaybeNullableRowTyped<T> {}
macro_rules! marker_types {
($( $(#[$meta:meta])* $name:ident; )+) => {
$(
$(#[$meta])*
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
pub struct $name;
)+
};
}
marker_types! {
PgBool;
PgI8;
PgI16;
PgI32;
PgI64;
PgF32;
PgF64;
PgString;
PgBytea;
PgHstore;
PgTimestamp;
PgTimestampTz;
PgInet;
PgDate;
PgTime;
PgUuid;
PgJson;
}
macro_rules! impl_query_types {
($( $marker:ty => param: $param:ty, row: $row:ty; )+ ) => {
$(
impl QueryParamTyped<$marker> for $param {}
impl QueryParamTyped<$marker> for Option<$param> {}
impl QueryRowTyped<$marker> for $row {}
impl QueryNullableRowTyped<$marker> for Option<$row> {}
impl QueryMaybeNullableRowTyped<$marker> for $row {}
impl QueryMaybeNullableRowTyped<$marker> for Option<$row> {}
)+
};
}
impl QueryParamTyped<PgString> for &str {}
impl QueryParamTyped<PgString> for Option<&str> {}
impl QueryParamTyped<PgBytea> for &[u8] {}
impl QueryParamTyped<PgBytea> for Option<&[u8]> {}
impl_query_types! {
PgBool => param: bool, row: bool;
PgI8 => param: i8, row: i8;
PgI16 => param: i16, row: i16;
PgI32 => param: i32, row: i32;
PgI64 => param: i64, row: i64;
PgF32 => param: f32, row: f32;
PgF64 => param: f64, row: f64;
PgString => param: String, row: String;
PgBytea => param: Vec<u8>, row: Vec<u8>;
PgHstore => param: HashMap<String, Option<String>>, row: HashMap<String, Option<String>>;
PgTimestamp => param: SystemTime, row: SystemTime;
PgTimestampTz => param: SystemTime, row: SystemTime;
PgInet => param: IpAddr, row: IpAddr;
}
impl FromSqlTyped<'_, PgBool> for bool {}
impl FromSqlTyped<'_, PgI8> for i8 {}
impl FromSqlTyped<'_, PgI16> for i16 {}
impl FromSqlTyped<'_, PgI32> for i32 {}
impl FromSqlTyped<'_, PgI64> for i64 {}
impl FromSqlTyped<'_, PgF32> for f32 {}
impl FromSqlTyped<'_, PgF64> for f64 {}
impl<'a> FromSqlTyped<'a, PgString> for &'a str {}
impl FromSqlTyped<'_, PgString> for String {}
impl<'a> FromSqlTyped<'a, PgBytea> for &'a [u8] {}
impl FromSqlTyped<'_, PgBytea> for Vec<u8> {}
impl FromSqlTyped<'_, PgHstore> for HashMap<String, Option<String>> {}
impl FromSqlTyped<'_, PgTimestamp> for SystemTime {}
impl FromSqlTyped<'_, PgTimestampTz> for SystemTime {}
impl FromSqlTyped<'_, PgInet> for IpAddr {}
#[cfg(feature = "with-time-0_3")]
impl_query_types! {
PgTimestamp => param: time_03::PrimitiveDateTime, row: time_03::PrimitiveDateTime;
PgTimestampTz => param: time_03::OffsetDateTime, row: time_03::OffsetDateTime;
PgDate => param: time_03::Date, row: time_03::Date;
PgTime => param: time_03::Time, row: time_03::Time;
}
#[cfg(feature = "with-time-0_3")]
impl<'a> FromSqlTyped<'a, PgTimestamp> for time_03::PrimitiveDateTime {}
#[cfg(feature = "with-time-0_3")]
impl<'a> FromSqlTyped<'a, PgTimestampTz> for time_03::OffsetDateTime {}
#[cfg(feature = "with-time-0_3")]
impl<'a> FromSqlTyped<'a, PgDate> for time_03::Date {}
#[cfg(feature = "with-time-0_3")]
impl<'a> FromSqlTyped<'a, PgTime> for time_03::Time {}
#[cfg(feature = "with-serde_json-1")]
impl_query_types! {
PgJson => param: serde_json_1::Value, row: serde_json_1::Value;
}
#[cfg(feature = "with-serde_json-1")]
impl<'a> FromSqlTyped<'a, PgJson> for serde_json_1::Value {}
#[cfg(feature = "with-serde_json-1")]
impl<T> QueryParamTyped<PgJson> for Json<T> where Json<T>: tokio_postgres::types::ToSql {}
#[cfg(feature = "with-serde_json-1")]
impl<T> QueryParamTyped<PgJson> for Option<Json<T>> where Json<T>: tokio_postgres::types::ToSql {}
#[cfg(feature = "with-serde_json-1")]
impl<T> QueryRowTyped<PgJson> for Json<T> where for<'a> Json<T>: tokio_postgres::types::FromSql<'a> {}
#[cfg(feature = "with-serde_json-1")]
impl<T> QueryNullableRowTyped<PgJson> for Option<Json<T>> where
for<'a> Json<T>: tokio_postgres::types::FromSql<'a>
{
}
#[cfg(feature = "with-serde_json-1")]
impl<T> QueryMaybeNullableRowTyped<PgJson> for Json<T> where
for<'a> Json<T>: tokio_postgres::types::FromSql<'a>
{
}
#[cfg(feature = "with-serde_json-1")]
impl<T> QueryMaybeNullableRowTyped<PgJson> for Option<Json<T>> where
for<'a> Json<T>: tokio_postgres::types::FromSql<'a>
{
}
#[cfg(feature = "with-serde_json-1")]
impl<'a, T> FromSqlTyped<'a, PgJson> for Json<T> where Json<T>: tokio_postgres::types::FromSql<'a> {}
#[cfg(feature = "with-uuid-1")]
impl_query_types! {
PgUuid => param: uuid_1::Uuid, row: uuid_1::Uuid;
}
#[cfg(feature = "with-uuid-1")]
impl<'a> FromSqlTyped<'a, PgUuid> for uuid_1::Uuid {}
#[cfg(all(test, feature = "with-serde_json-1"))]
mod tests {
use super::{
FromSqlTyped, PgJson, QueryMaybeNullableRowTyped, QueryNullableRowTyped, QueryParamTyped,
QueryRowTyped,
};
fn assert_param<T: QueryParamTyped<PgJson>>() {}
fn assert_row<T: QueryRowTyped<PgJson>>() {}
fn assert_nullable_row<T: QueryNullableRowTyped<PgJson>>() {}
fn assert_maybe_nullable_row<T: QueryMaybeNullableRowTyped<PgJson>>() {}
fn assert_from_sql<T>()
where
T: FromSqlTyped<'static, PgJson>,
{
}
#[test]
fn json_wrapper_is_supported_for_checked_queries() {
type JsonValue = super::Json<serde_json_1::Value>;
assert_param::<JsonValue>();
assert_param::<Option<JsonValue>>();
assert_row::<JsonValue>();
assert_nullable_row::<Option<JsonValue>>();
assert_maybe_nullable_row::<JsonValue>();
assert_maybe_nullable_row::<Option<JsonValue>>();
assert_from_sql::<JsonValue>();
}
}