derives: update transparent

This commit is contained in:
Ryan Leckey 2020-03-17 03:24:08 -07:00
parent 602e61ab27
commit 4fc5e65f5d
6 changed files with 296 additions and 299 deletions

View File

@ -61,25 +61,22 @@ fn expand_derive_decode_transparent(
// add db type for impl generics & where clause // add db type for impl generics & where clause
let mut generics = generics.clone(); let mut generics = generics.clone();
generics.params.insert(0, parse_quote!(DB: sqlx::Database)); generics.params.insert(0, parse_quote!(DB: sqlx::Database));
generics.params.insert(0, parse_quote!('de));
generics generics
.make_where_clause() .make_where_clause()
.predicates .predicates
.push(parse_quote!(#ty: sqlx::decode::Decode<DB>)); .push(parse_quote!(#ty: sqlx::decode::Decode<'de, DB>));
let (impl_generics, _, where_clause) = generics.split_for_impl(); let (impl_generics, _, where_clause) = generics.split_for_impl();
Ok(quote!( let tts = quote!(
impl #impl_generics sqlx::decode::Decode<DB> for #ident #ty_generics #where_clause { impl #impl_generics sqlx::decode::Decode<'de, DB> for #ident #ty_generics #where_clause {
fn decode(raw: &[u8]) -> std::result::Result<Self, sqlx::decode::DecodeError> { fn decode(value: <DB as sqlx::database::HasRawValue<'de>>::RawValue) -> sqlx::Result<Self> {
<#ty as sqlx::decode::Decode<DB>>::decode(raw).map(Self) <#ty as sqlx::decode::Decode<'de, DB>>::decode(value).map(Self)
}
fn decode_null() -> std::result::Result<Self, sqlx::decode::DecodeError> {
<#ty as sqlx::decode::Decode<DB>>::decode_null().map(Self)
}
fn decode_nullable(raw: std::option::Option<&[u8]>) -> std::result::Result<Self, sqlx::decode::DecodeError> {
<#ty as sqlx::decode::Decode<DB>>::decode_nullable(raw).map(Self)
} }
} }
)) );
Ok(tts)
} }
fn expand_derive_decode_weak_enum( fn expand_derive_decode_weak_enum(
@ -166,7 +163,7 @@ fn expand_derive_decode_struct(
for field in fields { for field in fields {
let ty = &field.ty; let ty = &field.ty;
predicates.push(parse_quote!(#ty: sqlx::decode::Decode<sqlx::Postgres>)); predicates.push(parse_quote!(#ty: sqlx::decode::Decode<sqlx::Postgres>));
predicates.push(parse_quote!(sqlx::Postgres: sqlx::types::HasSqlType<#ty>)); predicates.push(parse_quote!(#ty: sqlx::types::Type<sqlx::Postgres>));
} }
let (impl_generics, _, where_clause) = generics.split_for_impl(); let (impl_generics, _, where_clause) = generics.split_for_impl();

View File

@ -70,10 +70,10 @@ fn expand_derive_encode_transparent(
Ok(quote!( Ok(quote!(
impl #impl_generics sqlx::encode::Encode<DB> for #ident #ty_generics #where_clause { impl #impl_generics sqlx::encode::Encode<DB> for #ident #ty_generics #where_clause {
fn encode(&self, buf: &mut std::vec::Vec<u8>) { fn encode(&self, buf: &mut DB::RawBuffer) {
sqlx::encode::Encode::encode(&self.0, buf) sqlx::encode::Encode::encode(&self.0, buf)
} }
fn encode_nullable(&self, buf: &mut std::vec::Vec<u8>) -> sqlx::encode::IsNull { fn encode_nullable(&self, buf: &mut DB::RawBuffer) -> sqlx::encode::IsNull {
sqlx::encode::Encode::encode_nullable(&self.0, buf) sqlx::encode::Encode::encode_nullable(&self.0, buf)
} }
fn size_hint(&self) -> usize { fn size_hint(&self) -> usize {

View File

@ -1,25 +1,25 @@
mod attributes; mod attributes;
mod decode; mod decode;
mod encode; mod encode;
mod has_sql_type; mod r#type;
pub(crate) use decode::expand_derive_decode; pub(crate) use decode::expand_derive_decode;
pub(crate) use encode::expand_derive_encode; pub(crate) use encode::expand_derive_encode;
pub(crate) use has_sql_type::expand_derive_has_sql_type; pub(crate) use r#type::expand_derive_type;
use std::iter::FromIterator; use std::iter::FromIterator;
use syn::DeriveInput; use syn::DeriveInput;
pub(crate) fn expand_derive_type(input: &DeriveInput) -> syn::Result<proc_macro2::TokenStream> { pub(crate) fn expand_derive_type_encode_decode(
input: &DeriveInput,
) -> syn::Result<proc_macro2::TokenStream> {
let encode_tts = expand_derive_encode(input)?; let encode_tts = expand_derive_encode(input)?;
let decode_tts = expand_derive_decode(input)?; let decode_tts = expand_derive_decode(input)?;
let has_sql_type_tts = expand_derive_has_sql_type(input)?; let type_tts = expand_derive_type(input)?;
let combined = proc_macro2::TokenStream::from_iter( let combined = proc_macro2::TokenStream::from_iter(
encode_tts encode_tts.into_iter().chain(decode_tts).chain(type_tts),
.into_iter()
.chain(decode_tts)
.chain(has_sql_type_tts),
); );
Ok(combined) Ok(combined)
} }

View File

@ -10,7 +10,7 @@ use syn::{
FieldsUnnamed, Variant, FieldsUnnamed, Variant,
}; };
pub fn expand_derive_has_sql_type(input: &DeriveInput) -> syn::Result<proc_macro2::TokenStream> { pub fn expand_derive_type(input: &DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
let attrs = parse_attributes(&input.attrs)?; let attrs = parse_attributes(&input.attrs)?;
match &input.data { match &input.data {
Data::Struct(DataStruct { Data::Struct(DataStruct {
@ -56,37 +56,39 @@ fn expand_derive_has_sql_type_transparent(
// extract type generics // extract type generics
let generics = &input.generics; let generics = &input.generics;
let (impl_generics, ty_generics, _) = generics.split_for_impl(); let (_, ty_generics, _) = generics.split_for_impl();
// add db type for clause // add db type for clause
let mut generics = generics.clone(); let mut generics = generics.clone();
generics.params.insert(0, parse_quote!(DB: sqlx::Database));
generics generics
.make_where_clause() .make_where_clause()
.predicates .predicates
.push(parse_quote!(Self: sqlx::types::HasSqlType<#ty>)); .push(parse_quote!(#ty: sqlx::types::Type<DB>));
let (_, _, where_clause) = generics.split_for_impl(); let (impl_generics, _, where_clause) = generics.split_for_impl();
let mut tts = proc_macro2::TokenStream::new(); let mut tts = proc_macro2::TokenStream::new();
if cfg!(feature = "mysql") { // if cfg!(feature = "mysql") {
tts.extend(quote!( tts.extend(quote!(
impl #impl_generics sqlx::types::HasSqlType< #ident #ty_generics > for sqlx::MySql #where_clause { impl #impl_generics sqlx::types::Type< DB > for #ident #ty_generics #where_clause {
fn type_info() -> Self::TypeInfo { fn type_info() -> DB::TypeInfo {
<Self as HasSqlType<#ty>>::type_info() <#ty as sqlx::Type<DB>>::type_info()
}
} }
)); }
} ));
if cfg!(feature = "postgres") { // }
tts.extend(quote!(
impl #impl_generics sqlx::types::HasSqlType< #ident #ty_generics > for sqlx::Postgres #where_clause { // if cfg!(feature = "postgres") {
fn type_info() -> Self::TypeInfo { // tts.extend(quote!(
<Self as HasSqlType<#ty>>::type_info() // impl #impl_generics sqlx::types::HasSqlType< sqlx::Postgres > #ident #ty_generics #where_clause {
} // fn type_info() -> Self::TypeInfo {
} // <Self as HasSqlType<#ty>>::type_info()
)); // }
} // }
// ));
// }
Ok(tts) Ok(tts)
} }

View File

@ -169,19 +169,10 @@ pub fn derive_decode(tokenstream: TokenStream) -> TokenStream {
} }
} }
#[proc_macro_derive(HasSqlType, attributes(sqlx))]
pub fn derive_has_sql_type(tokenstream: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(tokenstream as syn::DeriveInput);
match derives::expand_derive_has_sql_type(&input) {
Ok(ts) => ts.into(),
Err(e) => e.to_compile_error().into(),
}
}
#[proc_macro_derive(Type, attributes(sqlx))] #[proc_macro_derive(Type, attributes(sqlx))]
pub fn derive_type(tokenstream: TokenStream) -> TokenStream { pub fn derive_type(tokenstream: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(tokenstream as syn::DeriveInput); let input = syn::parse_macro_input!(tokenstream as syn::DeriveInput);
match derives::expand_derive_type(&input) { match derives::expand_derive_type_encode_decode(&input) {
Ok(ts) => ts.into(), Ok(ts) => ts.into(),
Err(e) => e.to_compile_error().into(), Err(e) => e.to_compile_error().into(),
} }

View File

@ -1,39 +1,40 @@
use sqlx::decode::Decode; use sqlx::decode::Decode;
use sqlx::encode::Encode; use sqlx::encode::Encode;
use sqlx::types::{HasSqlType, TypeInfo}; use sqlx::types::TypeInfo;
use sqlx::Type;
use std::fmt::Debug; use std::fmt::Debug;
#[derive(PartialEq, Debug, Encode, Decode, HasSqlType)] #[derive(PartialEq, Debug, Type)]
#[sqlx(transparent)] #[sqlx(transparent)]
struct Transparent(i32); struct Transparent(i32);
#[derive(PartialEq, Debug, Clone, Copy, Encode, Decode, HasSqlType)] // #[derive(PartialEq, Debug, Clone, Copy, Encode, Decode, HasSqlType)]
#[repr(i32)] // #[repr(i32)]
#[allow(dead_code)] // #[allow(dead_code)]
enum Weak { // enum Weak {
One, // One,
Two, // Two,
Three, // Three,
} // }
//
#[derive(PartialEq, Debug, Encode, Decode, HasSqlType)] // #[derive(PartialEq, Debug, Encode, Decode, HasSqlType)]
#[sqlx(postgres(oid = 10101010))] // #[sqlx(postgres(oid = 10101010))]
#[allow(dead_code)] // #[allow(dead_code)]
enum Strong { // enum Strong {
One, // One,
Two, // Two,
#[sqlx(rename = "four")] // #[sqlx(rename = "four")]
Three, // Three,
} // }
//
#[derive(PartialEq, Debug, Encode, Decode, HasSqlType)] // #[derive(PartialEq, Debug, Encode, Decode, HasSqlType)]
#[sqlx(postgres(oid = 20202020))] // #[sqlx(postgres(oid = 20202020))]
#[allow(dead_code)] // #[allow(dead_code)]
struct Struct { // struct Struct {
field1: String, // field1: String,
field2: i64, // field2: i64,
field3: bool, // field3: bool,
} // }
#[test] #[test]
#[cfg(feature = "mysql")] #[cfg(feature = "mysql")]
@ -48,7 +49,7 @@ fn encode_transparent_postgres() {
} }
#[allow(dead_code)] #[allow(dead_code)]
fn encode_transparent<DB: sqlx::Database>() fn encode_transparent<DB: sqlx::Database<RawBuffer = Vec<u8>>>()
where where
Transparent: Encode<DB>, Transparent: Encode<DB>,
i32: Encode<DB>, i32: Encode<DB>,
@ -63,124 +64,124 @@ where
assert_eq!(encoded, encoded_orig); assert_eq!(encoded, encoded_orig);
} }
//
#[test] // #[test]
#[cfg(feature = "mysql")] // #[cfg(feature = "mysql")]
fn encode_weak_enum_mysql() { // fn encode_weak_enum_mysql() {
encode_weak_enum::<sqlx::MySql>(); // encode_weak_enum::<sqlx::MySql>();
} // }
//
#[test] // #[test]
#[cfg(feature = "postgres")] // #[cfg(feature = "postgres")]
fn encode_weak_enum_postgres() { // fn encode_weak_enum_postgres() {
encode_weak_enum::<sqlx::Postgres>(); // encode_weak_enum::<sqlx::Postgres>();
} // }
//
#[allow(dead_code)] // #[allow(dead_code)]
fn encode_weak_enum<DB: sqlx::Database>() // fn encode_weak_enum<DB: sqlx::Database<RawBuffer = Vec<u8>>>()
where // where
Weak: Encode<DB>, // Weak: Encode<DB>,
i32: Encode<DB>, // i32: Encode<DB>,
{ // {
for example in [Weak::One, Weak::Two, Weak::Three].iter() { // for example in [Weak::One, Weak::Two, Weak::Three].iter() {
let mut encoded = Vec::new(); // let mut encoded = Vec::new();
let mut encoded_orig = Vec::new(); // let mut encoded_orig = Vec::new();
//
Encode::<DB>::encode(example, &mut encoded); // Encode::<DB>::encode(example, &mut encoded);
Encode::<DB>::encode(&(*example as i32), &mut encoded_orig); // Encode::<DB>::encode(&(*example as i32), &mut encoded_orig);
//
assert_eq!(encoded, encoded_orig); // assert_eq!(encoded, encoded_orig);
} // }
} // }
//
#[test] // #[test]
#[cfg(feature = "mysql")] // #[cfg(feature = "mysql")]
fn encode_strong_enum_mysql() { // fn encode_strong_enum_mysql() {
encode_strong_enum::<sqlx::MySql>(); // encode_strong_enum::<sqlx::MySql>();
} // }
//
#[test] // #[test]
#[cfg(feature = "postgres")] // #[cfg(feature = "postgres")]
fn encode_strong_enum_postgres() { // fn encode_strong_enum_postgres() {
encode_strong_enum::<sqlx::Postgres>(); // encode_strong_enum::<sqlx::Postgres>();
} // }
//
#[allow(dead_code)] // #[allow(dead_code)]
fn encode_strong_enum<DB: sqlx::Database>() // fn encode_strong_enum<DB: sqlx::Database<RawBuffer = Vec<u8>>>()
where // where
Strong: Encode<DB>, // Strong: Encode<DB>,
str: Encode<DB>, // str: Encode<DB>,
{ // {
for (example, name) in [ // for (example, name) in [
(Strong::One, "One"), // (Strong::One, "One"),
(Strong::Two, "Two"), // (Strong::Two, "Two"),
(Strong::Three, "four"), // (Strong::Three, "four"),
] // ]
.iter() // .iter()
{ // {
let mut encoded = Vec::new(); // let mut encoded = Vec::new();
let mut encoded_orig = Vec::new(); // let mut encoded_orig = Vec::new();
//
Encode::<DB>::encode(example, &mut encoded); // Encode::<DB>::encode(example, &mut encoded);
Encode::<DB>::encode(*name, &mut encoded_orig); // Encode::<DB>::encode(*name, &mut encoded_orig);
//
assert_eq!(encoded, encoded_orig); // assert_eq!(encoded, encoded_orig);
} // }
} // }
//
#[test] // #[test]
#[cfg(feature = "postgres")] // #[cfg(feature = "postgres")]
fn encode_struct_postgres() { // fn encode_struct_postgres() {
let field1 = "Foo".to_string(); // let field1 = "Foo".to_string();
let field2 = 3; // let field2 = 3;
let field3 = false; // let field3 = false;
//
let example = Struct { // let example = Struct {
field1: field1.clone(), // field1: field1.clone(),
field2, // field2,
field3, // field3,
}; // };
//
let mut encoded = Vec::new(); // let mut encoded = Vec::new();
Encode::<sqlx::Postgres>::encode(&example, &mut encoded); // Encode::<sqlx::Postgres>::encode(&example, &mut encoded);
//
let string_oid = <sqlx::Postgres as HasSqlType<String>>::type_info().oid(); // let string_oid = <sqlx::Postgres as HasSqlType<String>>::type_info().oid();
let i64_oid = <sqlx::Postgres as HasSqlType<i64>>::type_info().oid(); // let i64_oid = <sqlx::Postgres as HasSqlType<i64>>::type_info().oid();
let bool_oid = <sqlx::Postgres as HasSqlType<bool>>::type_info().oid(); // let bool_oid = <sqlx::Postgres as HasSqlType<bool>>::type_info().oid();
//
// 3 columns // // 3 columns
assert_eq!(&[0, 0, 0, 3], &encoded[..4]); // assert_eq!(&[0, 0, 0, 3], &encoded[..4]);
let encoded = &encoded[4..]; // let encoded = &encoded[4..];
//
// check field1 (string) // // check field1 (string)
assert_eq!(&string_oid.to_be_bytes(), &encoded[0..4]); // assert_eq!(&string_oid.to_be_bytes(), &encoded[0..4]);
assert_eq!(&(field1.len() as u32).to_be_bytes(), &encoded[4..8]); // assert_eq!(&(field1.len() as u32).to_be_bytes(), &encoded[4..8]);
assert_eq!(field1.as_bytes(), &encoded[8..8 + field1.len()]); // assert_eq!(field1.as_bytes(), &encoded[8..8 + field1.len()]);
let encoded = &encoded[8 + field1.len()..]; // let encoded = &encoded[8 + field1.len()..];
//
// check field2 (i64) // // check field2 (i64)
assert_eq!(&i64_oid.to_be_bytes(), &encoded[0..4]); // assert_eq!(&i64_oid.to_be_bytes(), &encoded[0..4]);
assert_eq!(&8u32.to_be_bytes(), &encoded[4..8]); // assert_eq!(&8u32.to_be_bytes(), &encoded[4..8]);
assert_eq!(field2.to_be_bytes(), &encoded[8..16]); // assert_eq!(field2.to_be_bytes(), &encoded[8..16]);
let encoded = &encoded[16..]; // let encoded = &encoded[16..];
//
// check field3 (bool) // // check field3 (bool)
assert_eq!(&bool_oid.to_be_bytes(), &encoded[0..4]); // assert_eq!(&bool_oid.to_be_bytes(), &encoded[0..4]);
assert_eq!(&1u32.to_be_bytes(), &encoded[4..8]); // assert_eq!(&1u32.to_be_bytes(), &encoded[4..8]);
assert_eq!(field3, encoded[8] != 0); // assert_eq!(field3, encoded[8] != 0);
let encoded = &encoded[9..]; // let encoded = &encoded[9..];
//
assert!(encoded.is_empty()); // assert!(encoded.is_empty());
//
let string_size = <String as Encode<sqlx::Postgres>>::size_hint(&field1); // let string_size = <String as Encode<sqlx::Postgres>>::size_hint(&field1);
let i64_size = <i64 as Encode<sqlx::Postgres>>::size_hint(&field2); // let i64_size = <i64 as Encode<sqlx::Postgres>>::size_hint(&field2);
let bool_size = <bool as Encode<sqlx::Postgres>>::size_hint(&field3); // let bool_size = <bool as Encode<sqlx::Postgres>>::size_hint(&field3);
//
assert_eq!( // assert_eq!(
4 + 3 * (4 + 4) + string_size + i64_size + bool_size, // 4 + 3 * (4 + 4) + string_size + i64_size + bool_size,
example.size_hint() // example.size_hint()
); // );
} // }
#[test] #[test]
#[cfg(feature = "mysql")] #[cfg(feature = "mysql")]
@ -193,119 +194,125 @@ fn decode_transparent_mysql() {
fn decode_transparent_postgres() { fn decode_transparent_postgres() {
decode_with_db::<sqlx::Postgres, Transparent>(Transparent(0x1122_3344)); decode_with_db::<sqlx::Postgres, Transparent>(Transparent(0x1122_3344));
} }
//
#[test] // #[test]
#[cfg(feature = "mysql")] // #[cfg(feature = "mysql")]
fn decode_weak_enum_mysql() { // fn decode_weak_enum_mysql() {
decode_with_db::<sqlx::MySql, Weak>(Weak::One); // decode_with_db::<sqlx::MySql, Weak>(Weak::One);
decode_with_db::<sqlx::MySql, Weak>(Weak::Two); // decode_with_db::<sqlx::MySql, Weak>(Weak::Two);
decode_with_db::<sqlx::MySql, Weak>(Weak::Three); // decode_with_db::<sqlx::MySql, Weak>(Weak::Three);
} // }
//
#[test] // #[test]
#[cfg(feature = "postgres")] // #[cfg(feature = "postgres")]
fn decode_weak_enum_postgres() { // fn decode_weak_enum_postgres() {
decode_with_db::<sqlx::Postgres, Weak>(Weak::One); // decode_with_db::<sqlx::Postgres, Weak>(Weak::One);
decode_with_db::<sqlx::Postgres, Weak>(Weak::Two); // decode_with_db::<sqlx::Postgres, Weak>(Weak::Two);
decode_with_db::<sqlx::Postgres, Weak>(Weak::Three); // decode_with_db::<sqlx::Postgres, Weak>(Weak::Three);
} // }
//
#[test] // #[test]
#[cfg(feature = "mysql")] // #[cfg(feature = "mysql")]
fn decode_strong_enum_mysql() { // fn decode_strong_enum_mysql() {
decode_with_db::<sqlx::MySql, Strong>(Strong::One); // decode_with_db::<sqlx::MySql, Strong>(Strong::One);
decode_with_db::<sqlx::MySql, Strong>(Strong::Two); // decode_with_db::<sqlx::MySql, Strong>(Strong::Two);
decode_with_db::<sqlx::MySql, Strong>(Strong::Three); // decode_with_db::<sqlx::MySql, Strong>(Strong::Three);
} // }
//
#[test] // #[test]
#[cfg(feature = "postgres")] // #[cfg(feature = "postgres")]
fn decode_strong_enum_postgres() { // fn decode_strong_enum_postgres() {
decode_with_db::<sqlx::Postgres, Strong>(Strong::One); // decode_with_db::<sqlx::Postgres, Strong>(Strong::One);
decode_with_db::<sqlx::Postgres, Strong>(Strong::Two); // decode_with_db::<sqlx::Postgres, Strong>(Strong::Two);
decode_with_db::<sqlx::Postgres, Strong>(Strong::Three); // decode_with_db::<sqlx::Postgres, Strong>(Strong::Three);
} // }
//
#[test] // #[test]
#[cfg(feature = "postgres")] // #[cfg(feature = "postgres")]
fn decode_struct_postgres() { // fn decode_struct_postgres() {
decode_with_db::<sqlx::Postgres, Struct>(Struct { // decode_with_db::<sqlx::Postgres, Struct>(Struct {
field1: "Foo".to_string(), // field1: "Foo".to_string(),
field2: 3, // field2: 3,
field3: true, // field3: true,
}); // });
} // }
//
#[allow(dead_code)] #[allow(dead_code)]
fn decode_with_db<DB: sqlx::Database, V: Decode<DB> + Encode<DB> + PartialEq + Debug>(example: V) { fn decode_with_db<
DB: sqlx::Database<RawBuffer = Vec<u8>>,
V: for<'de> Decode<'de, DB> + Encode<DB> + PartialEq + Debug,
>(
example: V,
) {
let mut encoded = Vec::new(); let mut encoded = Vec::new();
Encode::<DB>::encode(&example, &mut encoded); Encode::<DB>::encode(&example, &mut encoded);
let decoded = V::decode(&encoded).unwrap(); // let decoded = V::decode(&encoded).unwrap();
assert_eq!(example, decoded); // assert_eq!(example, decoded);
} }
#[test] #[test]
#[cfg(feature = "mysql")] #[cfg(feature = "mysql")]
fn has_sql_type_transparent_mysql() { fn type_transparent_mysql() {
has_sql_type_transparent::<sqlx::MySql>(); type_transparent::<sqlx::MySql>();
} }
#[test] #[test]
#[cfg(feature = "postgres")] #[cfg(feature = "postgres")]
fn has_sql_type_transparent_postgres() { fn type_transparent_postgres() {
has_sql_type_transparent::<sqlx::Postgres>(); type_transparent::<sqlx::Postgres>();
} }
#[allow(dead_code)] #[allow(dead_code)]
fn has_sql_type_transparent<DB: sqlx::Database>() fn type_transparent<DB: sqlx::Database<RawBuffer = Vec<u8>>>()
where where
DB: HasSqlType<Transparent> + HasSqlType<i32>, Transparent: Type<DB>,
i32: Type<DB>,
{ {
let info: DB::TypeInfo = <DB as HasSqlType<Transparent>>::type_info(); let info: DB::TypeInfo = <Transparent as Type<DB>>::type_info();
let info_orig: DB::TypeInfo = <DB as HasSqlType<i32>>::type_info(); let info_orig: DB::TypeInfo = <i32 as Type<DB>>::type_info();
assert!(info.compatible(&info_orig)); assert!(info.compatible(&info_orig));
} }
//
#[test] // #[test]
#[cfg(feature = "mysql")] // #[cfg(feature = "mysql")]
fn has_sql_type_weak_enum_mysql() { // fn type_weak_enum_mysql() {
has_sql_type_weak_enum::<sqlx::MySql>(); // type_weak_enum::<sqlx::MySql>();
} // }
//
#[test] // #[test]
#[cfg(feature = "postgres")] // #[cfg(feature = "postgres")]
fn has_sql_type_weak_enum_postgres() { // fn type_weak_enum_postgres() {
has_sql_type_weak_enum::<sqlx::Postgres>(); // type_weak_enum::<sqlx::Postgres>();
} // }
//
#[allow(dead_code)] // #[allow(dead_code)]
fn has_sql_type_weak_enum<DB: sqlx::Database>() // fn type_weak_enum<DB: sqlx::Database<RawBuffer = Vec<u8>>>()
where // where
DB: HasSqlType<Weak> + HasSqlType<i32>, // DB: HasSqlType<Weak> + HasSqlType<i32>,
{ // {
let info: DB::TypeInfo = <DB as HasSqlType<Weak>>::type_info(); // let info: DB::TypeInfo = <DB as HasSqlType<Weak>>::type_info();
let info_orig: DB::TypeInfo = <DB as HasSqlType<i32>>::type_info(); // let info_orig: DB::TypeInfo = <DB as HasSqlType<i32>>::type_info();
assert!(info.compatible(&info_orig)); // assert!(info.compatible(&info_orig));
} // }
//
#[test] // #[test]
#[cfg(feature = "mysql")] // #[cfg(feature = "mysql")]
fn has_sql_type_strong_enum_mysql() { // fn type_strong_enum_mysql() {
let info: sqlx::mysql::MySqlTypeInfo = <sqlx::MySql as HasSqlType<Strong>>::type_info(); // let info: sqlx::mysql::MySqlTypeInfo = <sqlx::MySql as HasSqlType<Strong>>::type_info();
assert!(info.compatible(&sqlx::mysql::MySqlTypeInfo::r#enum())) // assert!(info.compatible(&sqlx::mysql::MySqlTypeInfo::r#enum()))
} // }
//
#[test] // #[test]
#[cfg(feature = "postgres")] // #[cfg(feature = "postgres")]
fn has_sql_type_strong_enum_postgres() { // fn type_strong_enum_postgres() {
let info: sqlx::postgres::PgTypeInfo = <sqlx::Postgres as HasSqlType<Strong>>::type_info(); // let info: sqlx::postgres::PgTypeInfo = <sqlx::Postgres as HasSqlType<Strong>>::type_info();
assert!(info.compatible(&sqlx::postgres::PgTypeInfo::with_oid(10101010))) // assert!(info.compatible(&sqlx::postgres::PgTypeInfo::with_oid(10101010)))
} // }
//
#[test] // #[test]
#[cfg(feature = "postgres")] // #[cfg(feature = "postgres")]
fn has_sql_type_struct_postgres() { // fn type_struct_postgres() {
let info: sqlx::postgres::PgTypeInfo = <sqlx::Postgres as HasSqlType<Struct>>::type_info(); // let info: sqlx::postgres::PgTypeInfo = <sqlx::Postgres as HasSqlType<Struct>>::type_info();
assert!(info.compatible(&sqlx::postgres::PgTypeInfo::with_oid(20202020))) // assert!(info.compatible(&sqlx::postgres::PgTypeInfo::with_oid(20202020)))
} // }