diff --git a/.github/workflows/sqlx.yml b/.github/workflows/sqlx.yml index 4b080b42d2..b9b5251ccb 100644 --- a/.github/workflows/sqlx.yml +++ b/.github/workflows/sqlx.yml @@ -104,6 +104,25 @@ jobs: cargo test -p sqlx-macros-core --all-features + + - name: Test sqlx-macros custom namespace + run: > + cargo test + -p sqlx-macros + --all-features + env: + SQLX_NAMESPACE: "external" + RUSTFLAGS: "--cfg sqlx_macros_namespace" + + # Should fail compilation since the env var is not set + # and the testing `sqlx_macros_namespace` cfg is enabled. + - name: Test sqlx-macros without namespace + run: > + cargo test + -p sqlx-macros + --all-features || true + env: + RUSTFLAGS: "--cfg sqlx_macros_namespace" # Note: use `--lib` to not run integration tests that require a DB - name: Test sqlx diff --git a/Cargo.lock b/Cargo.lock index 79906bb607..352ab60aef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3729,6 +3729,7 @@ version = "0.9.0-alpha.1" dependencies = [ "proc-macro2", "quote", + "sqlx", "sqlx-core", "sqlx-macros-core", "syn 2.0.96", diff --git a/sqlx-macros-core/src/derives/decode.rs b/sqlx-macros-core/src/derives/decode.rs index 7af9643d93..6b1579df13 100644 --- a/sqlx-macros-core/src/derives/decode.rs +++ b/sqlx-macros-core/src/derives/decode.rs @@ -9,26 +9,26 @@ use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{ parse_quote, Arm, Data, DataEnum, DataStruct, DeriveInput, Field, Fields, FieldsNamed, - FieldsUnnamed, Stmt, TypeParamBound, Variant, + FieldsUnnamed, Ident, Stmt, TypeParamBound, Variant, }; -pub fn expand_derive_decode(input: &DeriveInput) -> syn::Result { +pub fn expand_derive_decode(input: &DeriveInput, crate_name: &Ident) -> syn::Result { let attrs = parse_container_attributes(&input.attrs)?; match &input.data { Data::Struct(DataStruct { fields: Fields::Unnamed(FieldsUnnamed { unnamed, .. }), .. }) if unnamed.len() == 1 => { - expand_derive_decode_transparent(input, unnamed.first().unwrap()) + expand_derive_decode_transparent(input, unnamed.first().unwrap(), crate_name) } Data::Enum(DataEnum { variants, .. }) => match attrs.repr { - Some(_) => expand_derive_decode_weak_enum(input, variants), - None => expand_derive_decode_strong_enum(input, variants), + Some(_) => expand_derive_decode_weak_enum(input, variants, crate_name), + None => expand_derive_decode_strong_enum(input, variants, crate_name), }, Data::Struct(DataStruct { fields: Fields::Named(FieldsNamed { named, .. }), .. - }) => expand_derive_decode_struct(input, named), + }) => expand_derive_decode_struct(input, named, crate_name), Data::Union(_) => Err(syn::Error::new_spanned(input, "unions are not supported")), Data::Struct(DataStruct { fields: Fields::Unnamed(..), @@ -50,6 +50,7 @@ pub fn expand_derive_decode(input: &DeriveInput) -> syn::Result { fn expand_derive_decode_transparent( input: &DeriveInput, field: &Field, + crate_name: &Ident, ) -> syn::Result { check_transparent_attributes(input, field)?; @@ -64,26 +65,26 @@ fn expand_derive_decode_transparent( let mut generics = generics.clone(); generics .params - .insert(0, parse_quote!(DB: ::sqlx::Database)); + .insert(0, parse_quote!(DB: ::#crate_name::Database)); generics.params.insert(0, parse_quote!('r)); generics .make_where_clause() .predicates - .push(parse_quote!(#ty: ::sqlx::decode::Decode<'r, DB>)); + .push(parse_quote!(#ty: ::#crate_name::decode::Decode<'r, DB>)); let (impl_generics, _, where_clause) = generics.split_for_impl(); let tts = quote!( #[automatically_derived] - impl #impl_generics ::sqlx::decode::Decode<'r, DB> for #ident #ty_generics #where_clause { + impl #impl_generics ::#crate_name::decode::Decode<'r, DB> for #ident #ty_generics #where_clause { fn decode( - value: ::ValueRef<'r>, + value: ::ValueRef<'r>, ) -> ::std::result::Result< Self, ::std::boxed::Box< dyn ::std::error::Error + 'static + ::std::marker::Send + ::std::marker::Sync, >, > { - <#ty as ::sqlx::decode::Decode<'r, DB>>::decode(value).map(Self) + <#ty as ::#crate_name::decode::Decode<'r, DB>>::decode(value).map(Self) } } ); @@ -94,6 +95,7 @@ fn expand_derive_decode_transparent( fn expand_derive_decode_weak_enum( input: &DeriveInput, variants: &Punctuated, + crate_name: &Ident, ) -> syn::Result { let attr = check_weak_enum_attributes(input, variants)?; let repr = attr.repr.unwrap(); @@ -113,23 +115,23 @@ fn expand_derive_decode_weak_enum( Ok(quote!( #[automatically_derived] - impl<'r, DB: ::sqlx::Database> ::sqlx::decode::Decode<'r, DB> for #ident + impl<'r, DB: ::#crate_name::Database> ::#crate_name::decode::Decode<'r, DB> for #ident where - #repr: ::sqlx::decode::Decode<'r, DB>, + #repr: ::#crate_name::decode::Decode<'r, DB>, { fn decode( - value: ::ValueRef<'r>, + value: ::ValueRef<'r>, ) -> ::std::result::Result< Self, ::std::boxed::Box< dyn ::std::error::Error + 'static + ::std::marker::Send + ::std::marker::Sync, >, > { - let value = <#repr as ::sqlx::decode::Decode<'r, DB>>::decode(value)?; + let value = <#repr as ::#crate_name::decode::Decode<'r, DB>>::decode(value)?; match value { #(#arms)* - _ => ::std::result::Result::Err(::std::boxed::Box::new(::sqlx::Error::Decode( + _ => ::std::result::Result::Err(::std::boxed::Box::new(::#crate_name::Error::Decode( ::std::format!("invalid value {:?} for enum {}", value, #ident_s).into(), ))) } @@ -141,6 +143,7 @@ fn expand_derive_decode_weak_enum( fn expand_derive_decode_strong_enum( input: &DeriveInput, variants: &Punctuated, + crate_name: &Ident, ) -> syn::Result { let cattr = check_strong_enum_attributes(input, variants)?; @@ -176,9 +179,9 @@ fn expand_derive_decode_strong_enum( if cfg!(feature = "mysql") { tts.extend(quote!( #[automatically_derived] - impl<'r> ::sqlx::decode::Decode<'r, ::sqlx::mysql::MySql> for #ident { + impl<'r> ::#crate_name::decode::Decode<'r, ::#crate_name::mysql::MySql> for #ident { fn decode( - value: ::sqlx::mysql::MySqlValueRef<'r>, + value: ::#crate_name::mysql::MySqlValueRef<'r>, ) -> ::std::result::Result< Self, ::std::boxed::Box< @@ -188,9 +191,9 @@ fn expand_derive_decode_strong_enum( + ::std::marker::Sync, >, > { - let value = <&'r ::std::primitive::str as ::sqlx::decode::Decode< + let value = <&'r ::std::primitive::str as ::#crate_name::decode::Decode< 'r, - ::sqlx::mysql::MySql, + ::#crate_name::mysql::MySql, >>::decode(value)?; #values @@ -202,9 +205,9 @@ fn expand_derive_decode_strong_enum( if cfg!(feature = "postgres") { tts.extend(quote!( #[automatically_derived] - impl<'r> ::sqlx::decode::Decode<'r, ::sqlx::postgres::Postgres> for #ident { + impl<'r> ::#crate_name::decode::Decode<'r, ::#crate_name::postgres::Postgres> for #ident { fn decode( - value: ::sqlx::postgres::PgValueRef<'r>, + value: ::#crate_name::postgres::PgValueRef<'r>, ) -> ::std::result::Result< Self, ::std::boxed::Box< @@ -214,9 +217,9 @@ fn expand_derive_decode_strong_enum( + ::std::marker::Sync, >, > { - let value = <&'r ::std::primitive::str as ::sqlx::decode::Decode< + let value = <&'r ::std::primitive::str as ::#crate_name::decode::Decode< 'r, - ::sqlx::postgres::Postgres, + ::#crate_name::postgres::Postgres, >>::decode(value)?; #values @@ -228,9 +231,9 @@ fn expand_derive_decode_strong_enum( if cfg!(feature = "_sqlite") { tts.extend(quote!( #[automatically_derived] - impl<'r> ::sqlx::decode::Decode<'r, ::sqlx::sqlite::Sqlite> for #ident { + impl<'r> ::#crate_name::decode::Decode<'r, ::#crate_name::sqlite::Sqlite> for #ident { fn decode( - value: ::sqlx::sqlite::SqliteValueRef<'r>, + value: ::#crate_name::sqlite::SqliteValueRef<'r>, ) -> ::std::result::Result< Self, ::std::boxed::Box< @@ -240,9 +243,9 @@ fn expand_derive_decode_strong_enum( + ::std::marker::Sync, >, > { - let value = <&'r ::std::primitive::str as ::sqlx::decode::Decode< + let value = <&'r ::std::primitive::str as ::#crate_name::decode::Decode< 'r, - ::sqlx::sqlite::Sqlite, + ::#crate_name::sqlite::Sqlite, >>::decode(value)?; #values @@ -257,6 +260,7 @@ fn expand_derive_decode_strong_enum( fn expand_derive_decode_struct( input: &DeriveInput, fields: &Punctuated, + crate_name: &Ident, ) -> syn::Result { check_struct_attributes(input, fields)?; @@ -272,8 +276,8 @@ fn expand_derive_decode_struct( // add db type for impl generics & where clause for type_param in &mut generics.type_params_mut() { type_param.bounds.extend::<[TypeParamBound; 2]>([ - parse_quote!(for<'decode> ::sqlx::decode::Decode<'decode, ::sqlx::Postgres>), - parse_quote!(::sqlx::types::Type<::sqlx::Postgres>), + parse_quote!(for<'decode> ::#crate_name::decode::Decode<'decode, ::#crate_name::Postgres>), + parse_quote!(::#crate_name::types::Type<::#crate_name::Postgres>), ]); } @@ -294,11 +298,11 @@ fn expand_derive_decode_struct( tts.extend(quote!( #[automatically_derived] - impl #impl_generics ::sqlx::decode::Decode<'r, ::sqlx::Postgres> for #ident #ty_generics + impl #impl_generics ::#crate_name::decode::Decode<'r, ::#crate_name::Postgres> for #ident #ty_generics #where_clause { fn decode( - value: ::sqlx::postgres::PgValueRef<'r>, + value: ::#crate_name::postgres::PgValueRef<'r>, ) -> ::std::result::Result< Self, ::std::boxed::Box< @@ -308,7 +312,7 @@ fn expand_derive_decode_struct( + ::std::marker::Sync, >, > { - let mut decoder = ::sqlx::postgres::types::PgRecordDecoder::new(value)?; + let mut decoder = ::#crate_name::postgres::types::PgRecordDecoder::new(value)?; #(#reads)* diff --git a/sqlx-macros-core/src/derives/encode.rs b/sqlx-macros-core/src/derives/encode.rs index 9f26aba0a9..25f2279d5d 100644 --- a/sqlx-macros-core/src/derives/encode.rs +++ b/sqlx-macros-core/src/derives/encode.rs @@ -9,10 +9,10 @@ use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{ parse_quote, Data, DataEnum, DataStruct, DeriveInput, Expr, Field, Fields, FieldsNamed, - FieldsUnnamed, Lifetime, LifetimeParam, Stmt, TypeParamBound, Variant, + FieldsUnnamed, Ident, Lifetime, LifetimeParam, Stmt, TypeParamBound, Variant, }; -pub fn expand_derive_encode(input: &DeriveInput) -> syn::Result { +pub fn expand_derive_encode(input: &DeriveInput, crate_name: &Ident) -> syn::Result { let args = parse_container_attributes(&input.attrs)?; match &input.data { @@ -20,16 +20,16 @@ pub fn expand_derive_encode(input: &DeriveInput) -> syn::Result { fields: Fields::Unnamed(FieldsUnnamed { unnamed, .. }), .. }) if unnamed.len() == 1 => { - expand_derive_encode_transparent(input, unnamed.first().unwrap()) + expand_derive_encode_transparent(input, unnamed.first().unwrap(), crate_name) } Data::Enum(DataEnum { variants, .. }) => match args.repr { - Some(_) => expand_derive_encode_weak_enum(input, variants), - None => expand_derive_encode_strong_enum(input, variants), + Some(_) => expand_derive_encode_weak_enum(input, variants, crate_name), + None => expand_derive_encode_strong_enum(input, variants, crate_name), }, Data::Struct(DataStruct { fields: Fields::Named(FieldsNamed { named, .. }), .. - }) => expand_derive_encode_struct(input, named), + }) => expand_derive_encode_struct(input, named, crate_name), Data::Union(_) => Err(syn::Error::new_spanned(input, "unions are not supported")), Data::Struct(DataStruct { fields: Fields::Unnamed(..), @@ -51,6 +51,7 @@ pub fn expand_derive_encode(input: &DeriveInput) -> syn::Result { fn expand_derive_encode_transparent( input: &DeriveInput, field: &Field, + crate_name: &Ident, ) -> syn::Result { check_transparent_attributes(input, field)?; @@ -70,31 +71,31 @@ fn expand_derive_encode_transparent( generics .params - .insert(0, parse_quote!(DB: ::sqlx::Database)); + .insert(0, parse_quote!(DB: ::#crate_name::Database)); generics .make_where_clause() .predicates - .push(parse_quote!(#ty: ::sqlx::encode::Encode<#lifetime, DB>)); + .push(parse_quote!(#ty: ::#crate_name::encode::Encode<#lifetime, DB>)); let (impl_generics, _, where_clause) = generics.split_for_impl(); Ok(quote!( #[automatically_derived] - impl #impl_generics ::sqlx::encode::Encode<#lifetime, DB> for #ident #ty_generics + impl #impl_generics ::#crate_name::encode::Encode<#lifetime, DB> for #ident #ty_generics #where_clause { fn encode_by_ref( &self, - buf: &mut ::ArgumentBuffer<#lifetime>, - ) -> ::std::result::Result<::sqlx::encode::IsNull, ::sqlx::error::BoxDynError> { - <#ty as ::sqlx::encode::Encode<#lifetime, DB>>::encode_by_ref(&self.0, buf) + buf: &mut ::ArgumentBuffer<#lifetime>, + ) -> ::std::result::Result<::#crate_name::encode::IsNull, ::#crate_name::error::BoxDynError> { + <#ty as ::#crate_name::encode::Encode<#lifetime, DB>>::encode_by_ref(&self.0, buf) } fn produces(&self) -> Option { - <#ty as ::sqlx::encode::Encode<#lifetime, DB>>::produces(&self.0) + <#ty as ::#crate_name::encode::Encode<#lifetime, DB>>::produces(&self.0) } fn size_hint(&self) -> usize { - <#ty as ::sqlx::encode::Encode<#lifetime, DB>>::size_hint(&self.0) + <#ty as ::#crate_name::encode::Encode<#lifetime, DB>>::size_hint(&self.0) } } )) @@ -103,6 +104,7 @@ fn expand_derive_encode_transparent( fn expand_derive_encode_weak_enum( input: &DeriveInput, variants: &Punctuated, + crate_name: &Ident, ) -> syn::Result { let attr = check_weak_enum_attributes(input, variants)?; let repr = attr.repr.unwrap(); @@ -117,23 +119,23 @@ fn expand_derive_encode_weak_enum( Ok(quote!( #[automatically_derived] - impl<'q, DB: ::sqlx::Database> ::sqlx::encode::Encode<'q, DB> for #ident + impl<'q, DB: ::#crate_name::Database> ::#crate_name::encode::Encode<'q, DB> for #ident where - #repr: ::sqlx::encode::Encode<'q, DB>, + #repr: ::#crate_name::encode::Encode<'q, DB>, { fn encode_by_ref( &self, - buf: &mut ::ArgumentBuffer<'q>, - ) -> ::std::result::Result<::sqlx::encode::IsNull, ::sqlx::error::BoxDynError> { + buf: &mut ::ArgumentBuffer<'q>, + ) -> ::std::result::Result<::#crate_name::encode::IsNull, ::#crate_name::error::BoxDynError> { let value = match self { #(#values)* }; - <#repr as ::sqlx::encode::Encode>::encode_by_ref(&value, buf) + <#repr as ::#crate_name::encode::Encode>::encode_by_ref(&value, buf) } fn size_hint(&self) -> usize { - <#repr as ::sqlx::encode::Encode>::size_hint(&Default::default()) + <#repr as ::#crate_name::encode::Encode>::size_hint(&Default::default()) } } )) @@ -142,6 +144,7 @@ fn expand_derive_encode_weak_enum( fn expand_derive_encode_strong_enum( input: &DeriveInput, variants: &Punctuated, + crate_name: &Ident, ) -> syn::Result { let cattr = check_strong_enum_attributes(input, variants)?; @@ -167,19 +170,19 @@ fn expand_derive_encode_strong_enum( Ok(quote!( #[automatically_derived] - impl<'q, DB: ::sqlx::Database> ::sqlx::encode::Encode<'q, DB> for #ident + impl<'q, DB: ::#crate_name::Database> ::#crate_name::encode::Encode<'q, DB> for #ident where - &'q ::std::primitive::str: ::sqlx::encode::Encode<'q, DB>, + &'q ::std::primitive::str: ::#crate_name::encode::Encode<'q, DB>, { fn encode_by_ref( &self, - buf: &mut ::ArgumentBuffer<'q>, - ) -> ::std::result::Result<::sqlx::encode::IsNull, ::sqlx::error::BoxDynError> { + buf: &mut ::ArgumentBuffer<'q>, + ) -> ::std::result::Result<::#crate_name::encode::IsNull, ::#crate_name::error::BoxDynError> { let val = match self { #(#value_arms)* }; - <&::std::primitive::str as ::sqlx::encode::Encode<'q, DB>>::encode(val, buf) + <&::std::primitive::str as ::#crate_name::encode::Encode<'q, DB>>::encode(val, buf) } fn size_hint(&self) -> ::std::primitive::usize { @@ -187,7 +190,7 @@ fn expand_derive_encode_strong_enum( #(#value_arms)* }; - <&::std::primitive::str as ::sqlx::encode::Encode<'q, DB>>::size_hint(&val) + <&::std::primitive::str as ::#crate_name::encode::Encode<'q, DB>>::size_hint(&val) } } )) @@ -196,6 +199,7 @@ fn expand_derive_encode_strong_enum( fn expand_derive_encode_struct( input: &DeriveInput, fields: &Punctuated, + crate_name: &Ident, ) -> syn::Result { check_struct_attributes(input, fields)?; @@ -212,8 +216,8 @@ fn expand_derive_encode_struct( // add db type for impl generics & where clause for type_param in &mut generics.type_params_mut() { type_param.bounds.extend::<[TypeParamBound; 2]>([ - parse_quote!(for<'encode> ::sqlx::encode::Encode<'encode, ::sqlx::Postgres>), - parse_quote!(::sqlx::types::Type<::sqlx::Postgres>), + parse_quote!(for<'encode> ::#crate_name::encode::Encode<'encode, ::#crate_name::Postgres>), + parse_quote!(::#crate_name::types::Type<::#crate_name::Postgres>), ]); } @@ -234,26 +238,26 @@ fn expand_derive_encode_struct( let ty = &field.ty; parse_quote!( - <#ty as ::sqlx::encode::Encode<::sqlx::Postgres>>::size_hint(&self. #id) + <#ty as ::#crate_name::encode::Encode<::#crate_name::Postgres>>::size_hint(&self. #id) ) }); tts.extend(quote!( #[automatically_derived] - impl #impl_generics ::sqlx::encode::Encode<'_, ::sqlx::Postgres> for #ident #ty_generics + impl #impl_generics ::#crate_name::encode::Encode<'_, ::#crate_name::Postgres> for #ident #ty_generics #where_clause { fn encode_by_ref( &self, - buf: &mut ::sqlx::postgres::PgArgumentBuffer, - ) -> ::std::result::Result<::sqlx::encode::IsNull, ::sqlx::error::BoxDynError> { - let mut encoder = ::sqlx::postgres::types::PgRecordEncoder::new(buf); + buf: &mut ::#crate_name::postgres::PgArgumentBuffer, + ) -> ::std::result::Result<::#crate_name::encode::IsNull, ::#crate_name::error::BoxDynError> { + let mut encoder = ::#crate_name::postgres::types::PgRecordEncoder::new(buf); #(#writes)* encoder.finish(); - ::std::result::Result::Ok(::sqlx::encode::IsNull::No) + ::std::result::Result::Ok(::#crate_name::encode::IsNull::No) } fn size_hint(&self) -> ::std::primitive::usize { diff --git a/sqlx-macros-core/src/derives/mod.rs b/sqlx-macros-core/src/derives/mod.rs index 5f55ab5aea..8867a299f0 100644 --- a/sqlx-macros-core/src/derives/mod.rs +++ b/sqlx-macros-core/src/derives/mod.rs @@ -12,12 +12,15 @@ pub use row::expand_derive_from_row; use self::attributes::RenameAll; use heck::{ToKebabCase, ToLowerCamelCase, ToShoutySnakeCase, ToSnakeCase, ToUpperCamelCase}; use proc_macro2::TokenStream; -use syn::DeriveInput; +use syn::{DeriveInput, Ident}; -pub fn expand_derive_type_encode_decode(input: &DeriveInput) -> syn::Result { - let encode_tts = expand_derive_encode(input)?; - let decode_tts = expand_derive_decode(input)?; - let type_tts = expand_derive_type(input)?; +pub fn expand_derive_type_encode_decode( + input: &DeriveInput, + crate_name: Ident, +) -> syn::Result { + let encode_tts = expand_derive_encode(input, &crate_name)?; + let decode_tts = expand_derive_decode(input, &crate_name)?; + let type_tts = expand_derive_type(input, &crate_name)?; let combined = TokenStream::from_iter(encode_tts.into_iter().chain(decode_tts).chain(type_tts)); diff --git a/sqlx-macros-core/src/derives/row.rs b/sqlx-macros-core/src/derives/row.rs index 604986f90b..dce7c187b4 100644 --- a/sqlx-macros-core/src/derives/row.rs +++ b/sqlx-macros-core/src/derives/row.rs @@ -2,7 +2,7 @@ use proc_macro2::{Span, TokenStream}; use quote::quote; use syn::{ parse_quote, punctuated::Punctuated, token::Comma, Data, DataStruct, DeriveInput, Expr, Field, - Fields, FieldsNamed, FieldsUnnamed, Lifetime, Stmt, + Fields, FieldsNamed, FieldsUnnamed, Ident, Lifetime, Stmt, }; use super::{ @@ -10,17 +10,17 @@ use super::{ rename_all, }; -pub fn expand_derive_from_row(input: &DeriveInput) -> syn::Result { +pub fn expand_derive_from_row(input: &DeriveInput, crate_name: Ident) -> syn::Result { match &input.data { Data::Struct(DataStruct { fields: Fields::Named(FieldsNamed { named, .. }), .. - }) => expand_derive_from_row_struct(input, named), + }) => expand_derive_from_row_struct(input, named, crate_name), Data::Struct(DataStruct { fields: Fields::Unnamed(FieldsUnnamed { unnamed, .. }), .. - }) => expand_derive_from_row_struct_unnamed(input, unnamed), + }) => expand_derive_from_row_struct_unnamed(input, unnamed, crate_name), Data::Struct(DataStruct { fields: Fields::Unit, @@ -39,6 +39,7 @@ pub fn expand_derive_from_row(input: &DeriveInput) -> syn::Result { fn expand_derive_from_row_struct( input: &DeriveInput, fields: &Punctuated, + crate_name: Ident, ) -> syn::Result { let ident = &input.ident; @@ -53,7 +54,9 @@ fn expand_derive_from_row_struct( let (_, ty_generics, _) = generics.split_for_impl(); let mut generics = generics.clone(); - generics.params.insert(0, parse_quote!(R: ::sqlx::Row)); + generics + .params + .insert(0, parse_quote!(R: ::#crate_name::Row)); if provided { generics.params.insert(0, parse_quote!(#lifetime)); @@ -61,7 +64,7 @@ fn expand_derive_from_row_struct( let predicates = &mut generics.make_where_clause().predicates; - predicates.push(parse_quote!(&#lifetime ::std::primitive::str: ::sqlx::ColumnIndex)); + predicates.push(parse_quote!(&#lifetime ::std::primitive::str: ::#crate_name::ColumnIndex)); let container_attributes = parse_container_attributes(&input.attrs)?; @@ -101,29 +104,29 @@ fn expand_derive_from_row_struct( // (false, None, None) => { predicates - .push(parse_quote!(#ty: ::sqlx::decode::Decode<#lifetime, R::Database>)); - predicates.push(parse_quote!(#ty: ::sqlx::types::Type)); + .push(parse_quote!(#ty: ::#crate_name::decode::Decode<#lifetime, R::Database>)); + predicates.push(parse_quote!(#ty: ::#crate_name::types::Type)); parse_quote!(__row.try_get(#id_s)) } // Flatten (true, None, None) => { - predicates.push(parse_quote!(#ty: ::sqlx::FromRow<#lifetime, R>)); - parse_quote!(<#ty as ::sqlx::FromRow<#lifetime, R>>::from_row(__row)) + predicates.push(parse_quote!(#ty: ::#crate_name::FromRow<#lifetime, R>)); + parse_quote!(<#ty as ::#crate_name::FromRow<#lifetime, R>>::from_row(__row)) } // Flatten + Try from (true, Some(try_from), None) => { - predicates.push(parse_quote!(#try_from: ::sqlx::FromRow<#lifetime, R>)); + predicates.push(parse_quote!(#try_from: ::#crate_name::FromRow<#lifetime, R>)); parse_quote!( - <#try_from as ::sqlx::FromRow<#lifetime, R>>::from_row(__row) + <#try_from as ::#crate_name::FromRow<#lifetime, R>>::from_row(__row) .and_then(|v| { <#ty as ::std::convert::TryFrom::<#try_from>>::try_from(v) .map_err(|e| { // Triggers a lint warning if `TryFrom::Err = Infallible` #[allow(unreachable_code)] - ::sqlx::Error::ColumnDecode { + ::#crate_name::Error::ColumnDecode { index: #id_s.to_string(), - source: sqlx::__spec_error!(e), + source: ::#crate_name::__spec_error!(e), } }) }) @@ -136,8 +139,8 @@ fn expand_derive_from_row_struct( // Try from (false, Some(try_from), None) => { predicates - .push(parse_quote!(#try_from: ::sqlx::decode::Decode<#lifetime, R::Database>)); - predicates.push(parse_quote!(#try_from: ::sqlx::types::Type)); + .push(parse_quote!(#try_from: ::#crate_name::decode::Decode<#lifetime, R::Database>)); + predicates.push(parse_quote!(#try_from: ::#crate_name::types::Type)); parse_quote!( __row.try_get(#id_s) @@ -146,9 +149,9 @@ fn expand_derive_from_row_struct( .map_err(|e| { // Triggers a lint warning if `TryFrom::Err = Infallible` #[allow(unreachable_code)] - ::sqlx::Error::ColumnDecode { + ::#crate_name::Error::ColumnDecode { index: #id_s.to_string(), - source: sqlx::__spec_error!(e), + source: ::#crate_name::__spec_error!(e), } }) }) @@ -157,19 +160,19 @@ fn expand_derive_from_row_struct( // Try from + Json mandatory (false, Some(try_from), Some(JsonAttribute::NonNullable)) => { predicates - .push(parse_quote!(::sqlx::types::Json<#try_from>: ::sqlx::decode::Decode<#lifetime, R::Database>)); - predicates.push(parse_quote!(::sqlx::types::Json<#try_from>: ::sqlx::types::Type)); + .push(parse_quote!(::#crate_name::types::Json<#try_from>: ::#crate_name::decode::Decode<#lifetime, R::Database>)); + predicates.push(parse_quote!(::#crate_name::types::Json<#try_from>: ::#crate_name::types::Type)); parse_quote!( - __row.try_get::<::sqlx::types::Json<_>, _>(#id_s) + __row.try_get::<::#crate_name::types::Json<_>, _>(#id_s) .and_then(|v| { <#ty as ::std::convert::TryFrom::<#try_from>>::try_from(v.0) .map_err(|e| { // Triggers a lint warning if `TryFrom::Err = Infallible` #[allow(unreachable_code)] - ::sqlx::Error::ColumnDecode { + ::#crate_name::Error::ColumnDecode { index: #id_s.to_string(), - source: sqlx::__spec_error!(e), + source: ::#crate_name::__spec_error!(e), } }) }) @@ -182,24 +185,24 @@ fn expand_derive_from_row_struct( // Json (false, None, Some(JsonAttribute::NonNullable)) => { predicates - .push(parse_quote!(::sqlx::types::Json<#ty>: ::sqlx::decode::Decode<#lifetime, R::Database>)); - predicates.push(parse_quote!(::sqlx::types::Json<#ty>: ::sqlx::types::Type)); + .push(parse_quote!(::#crate_name::types::Json<#ty>: ::#crate_name::decode::Decode<#lifetime, R::Database>)); + predicates.push(parse_quote!(::#crate_name::types::Json<#ty>: ::#crate_name::types::Type)); - parse_quote!(__row.try_get::<::sqlx::types::Json<_>, _>(#id_s).map(|x| x.0)) + parse_quote!(__row.try_get::<::#crate_name::types::Json<_>, _>(#id_s).map(|x| x.0)) }, (false, None, Some(JsonAttribute::Nullable)) => { predicates - .push(parse_quote!(::core::option::Option<::sqlx::types::Json<#ty>>: ::sqlx::decode::Decode<#lifetime, R::Database>)); - predicates.push(parse_quote!(::core::option::Option<::sqlx::types::Json<#ty>>: ::sqlx::types::Type)); + .push(parse_quote!(::core::option::Option<::#crate_name::types::Json<#ty>>: ::#crate_name::decode::Decode<#lifetime, R::Database>)); + predicates.push(parse_quote!(::core::option::Option<::#crate_name::types::Json<#ty>>: ::#crate_name::types::Type)); - parse_quote!(__row.try_get::<::core::option::Option<::sqlx::types::Json<_>>, _>(#id_s).map(|x| x.and_then(|y| y.0))) + parse_quote!(__row.try_get::<::core::option::Option<::#crate_name::types::Json<_>>, _>(#id_s).map(|x| x.and_then(|y| y.0))) }, }; if attributes.default { Some(parse_quote!( let #id: #ty = #expr.or_else(|e| match e { - ::sqlx::Error::ColumnNotFound(_) => { + ::#crate_name::Error::ColumnNotFound(_) => { ::std::result::Result::Ok(Default::default()) }, e => ::std::result::Result::Err(e) @@ -208,7 +211,7 @@ fn expand_derive_from_row_struct( } else if container_attributes.default { Some(parse_quote!( let #id: #ty = #expr.or_else(|e| match e { - ::sqlx::Error::ColumnNotFound(_) => { + ::#crate_name::Error::ColumnNotFound(_) => { ::std::result::Result::Ok(__default.#id) }, e => ::std::result::Result::Err(e) @@ -228,8 +231,8 @@ fn expand_derive_from_row_struct( Ok(quote!( #[automatically_derived] - impl #impl_generics ::sqlx::FromRow<#lifetime, R> for #ident #ty_generics #where_clause { - fn from_row(__row: &#lifetime R) -> ::sqlx::Result { + impl #impl_generics ::#crate_name::FromRow<#lifetime, R> for #ident #ty_generics #where_clause { + fn from_row(__row: &#lifetime R) -> ::#crate_name::Result { #default_instance #(#reads)* @@ -245,6 +248,7 @@ fn expand_derive_from_row_struct( fn expand_derive_from_row_struct_unnamed( input: &DeriveInput, fields: &Punctuated, + crate_name: Ident, ) -> syn::Result { let ident = &input.ident; @@ -259,7 +263,9 @@ fn expand_derive_from_row_struct_unnamed( let (_, ty_generics, _) = generics.split_for_impl(); let mut generics = generics.clone(); - generics.params.insert(0, parse_quote!(R: ::sqlx::Row)); + generics + .params + .insert(0, parse_quote!(R: ::#crate_name::Row)); if provided { generics.params.insert(0, parse_quote!(#lifetime)); @@ -268,14 +274,14 @@ fn expand_derive_from_row_struct_unnamed( let predicates = &mut generics.make_where_clause().predicates; predicates.push(parse_quote!( - ::std::primitive::usize: ::sqlx::ColumnIndex + ::std::primitive::usize: ::#crate_name::ColumnIndex )); for field in fields { let ty = &field.ty; - predicates.push(parse_quote!(#ty: ::sqlx::decode::Decode<#lifetime, R::Database>)); - predicates.push(parse_quote!(#ty: ::sqlx::types::Type)); + predicates.push(parse_quote!(#ty: ::#crate_name::decode::Decode<#lifetime, R::Database>)); + predicates.push(parse_quote!(#ty: ::#crate_name::types::Type)); } let (impl_generics, _, where_clause) = generics.split_for_impl(); @@ -287,8 +293,8 @@ fn expand_derive_from_row_struct_unnamed( Ok(quote!( #[automatically_derived] - impl #impl_generics ::sqlx::FromRow<#lifetime, R> for #ident #ty_generics #where_clause { - fn from_row(row: &#lifetime R) -> ::sqlx::Result { + impl #impl_generics ::#crate_name::FromRow<#lifetime, R> for #ident #ty_generics #where_clause { + fn from_row(row: &#lifetime R) -> ::#crate_name::Result { ::std::result::Result::Ok(#ident ( #(#gets),* )) diff --git a/sqlx-macros-core/src/derives/type.rs b/sqlx-macros-core/src/derives/type.rs index 8ecd55230c..cd5df659cd 100644 --- a/sqlx-macros-core/src/derives/type.rs +++ b/sqlx-macros-core/src/derives/type.rs @@ -11,7 +11,7 @@ use syn::{ FieldsUnnamed, Variant, }; -pub fn expand_derive_type(input: &DeriveInput) -> syn::Result { +pub fn expand_derive_type(input: &DeriveInput, crate_name: &Ident) -> syn::Result { let attrs = parse_container_attributes(&input.attrs)?; match &input.data { // Newtype structs: @@ -21,7 +21,7 @@ pub fn expand_derive_type(input: &DeriveInput) -> syn::Result { .. }) => { if unnamed.len() == 1 { - expand_derive_has_sql_type_transparent(input, unnamed.first().unwrap()) + expand_derive_has_sql_type_transparent(input, unnamed.first().unwrap(), crate_name) } else { Err(syn::Error::new_spanned( input, @@ -34,7 +34,7 @@ pub fn expand_derive_type(input: &DeriveInput) -> syn::Result { Data::Struct(DataStruct { fields: Fields::Named(FieldsNamed { named, .. }), .. - }) => expand_derive_has_sql_type_struct(input, named), + }) => expand_derive_has_sql_type_struct(input, named, crate_name), Data::Struct(DataStruct { fields: Fields::Unit, .. @@ -45,9 +45,9 @@ pub fn expand_derive_type(input: &DeriveInput) -> syn::Result { Data::Enum(DataEnum { variants, .. }) => match attrs.repr { // Enums that encode to/from integers (weak enums) - Some(_) => expand_derive_has_sql_type_weak_enum(input, variants), + Some(_) => expand_derive_has_sql_type_weak_enum(input, variants, crate_name), // Enums that decode to/from strings (strong enums) - None => expand_derive_has_sql_type_strong_enum(input, variants), + None => expand_derive_has_sql_type_strong_enum(input, variants, crate_name), }, Data::Union(_) => Err(syn::Error::new_spanned(input, "unions are not supported")), } @@ -56,6 +56,7 @@ pub fn expand_derive_type(input: &DeriveInput) -> syn::Result { fn expand_derive_has_sql_type_transparent( input: &DeriveInput, field: &Field, + crate_name: &Ident, ) -> syn::Result { let attr = check_transparent_attributes(input, field)?; @@ -71,28 +72,28 @@ fn expand_derive_has_sql_type_transparent( generics .params - .insert(0, parse_quote!(DB: ::sqlx::Database)); + .insert(0, parse_quote!(DB: ::#crate_name::Database)); generics .make_where_clause() .predicates - .push(parse_quote!(#ty: ::sqlx::Type)); + .push(parse_quote!(#ty: ::#crate_name::Type)); let (impl_generics, _, where_clause) = generics.split_for_impl(); array_generics .make_where_clause() .predicates - .push(parse_quote!(#ty: ::sqlx::postgres::PgHasArrayType)); + .push(parse_quote!(#ty: ::#crate_name::postgres::PgHasArrayType)); let (array_impl_generics, _, array_where_clause) = array_generics.split_for_impl(); let mut tokens = quote!( #[automatically_derived] - impl #impl_generics ::sqlx::Type< DB > for #ident #ty_generics #where_clause { + impl #impl_generics ::#crate_name::Type< DB > for #ident #ty_generics #where_clause { fn type_info() -> DB::TypeInfo { - <#ty as ::sqlx::Type>::type_info() + <#ty as ::#crate_name::Type>::type_info() } fn compatible(ty: &DB::TypeInfo) -> ::std::primitive::bool { - <#ty as ::sqlx::Type>::compatible(ty) + <#ty as ::#crate_name::Type>::compatible(ty) } } ); @@ -100,10 +101,10 @@ fn expand_derive_has_sql_type_transparent( if cfg!(feature = "postgres") && !attr.no_pg_array { tokens.extend(quote!( #[automatically_derived] - impl #array_impl_generics ::sqlx::postgres::PgHasArrayType for #ident #ty_generics + impl #array_impl_generics ::#crate_name::postgres::PgHasArrayType for #ident #ty_generics #array_where_clause { - fn array_type_info() -> ::sqlx::postgres::PgTypeInfo { - <#ty as ::sqlx::postgres::PgHasArrayType>::array_type_info() + fn array_type_info() -> ::#crate_name::postgres::PgTypeInfo { + <#ty as ::#crate_name::postgres::PgHasArrayType>::array_type_info() } } )); @@ -119,9 +120,9 @@ fn expand_derive_has_sql_type_transparent( tts.extend(quote!( #[automatically_derived] - impl ::sqlx::Type<::sqlx::postgres::Postgres> for #ident #ty_generics { - fn type_info() -> ::sqlx::postgres::PgTypeInfo { - ::sqlx::postgres::PgTypeInfo::with_name(#ty_name) + impl ::#crate_name::Type<::#crate_name::postgres::Postgres> for #ident #ty_generics { + fn type_info() -> ::#crate_name::postgres::PgTypeInfo { + ::#crate_name::postgres::PgTypeInfo::with_name(#ty_name) } } )); @@ -133,22 +134,23 @@ fn expand_derive_has_sql_type_transparent( fn expand_derive_has_sql_type_weak_enum( input: &DeriveInput, variants: &Punctuated, + crate_name: &Ident, ) -> syn::Result { let attrs = check_weak_enum_attributes(input, variants)?; let repr = attrs.repr.unwrap(); let ident = &input.ident; let mut ts = quote!( #[automatically_derived] - impl ::sqlx::Type for #ident + impl ::#crate_name::Type for #ident where - #repr: ::sqlx::Type, + #repr: ::#crate_name::Type, { fn type_info() -> DB::TypeInfo { - <#repr as ::sqlx::Type>::type_info() + <#repr as ::#crate_name::Type>::type_info() } fn compatible(ty: &DB::TypeInfo) -> bool { - <#repr as ::sqlx::Type>::compatible(ty) + <#repr as ::#crate_name::Type>::compatible(ty) } } ); @@ -156,9 +158,9 @@ fn expand_derive_has_sql_type_weak_enum( if cfg!(feature = "postgres") && !attrs.no_pg_array { ts.extend(quote!( #[automatically_derived] - impl ::sqlx::postgres::PgHasArrayType for #ident { - fn array_type_info() -> ::sqlx::postgres::PgTypeInfo { - <#repr as ::sqlx::postgres::PgHasArrayType>::array_type_info() + impl ::#crate_name::postgres::PgHasArrayType for #ident { + fn array_type_info() -> ::#crate_name::postgres::PgTypeInfo { + <#repr as ::#crate_name::postgres::PgHasArrayType>::array_type_info() } } )); @@ -170,6 +172,7 @@ fn expand_derive_has_sql_type_weak_enum( fn expand_derive_has_sql_type_strong_enum( input: &DeriveInput, variants: &Punctuated, + crate_name: &Ident, ) -> syn::Result { let attributes = check_strong_enum_attributes(input, variants)?; @@ -179,9 +182,9 @@ fn expand_derive_has_sql_type_strong_enum( if cfg!(feature = "mysql") { tts.extend(quote!( #[automatically_derived] - impl ::sqlx::Type<::sqlx::MySql> for #ident { - fn type_info() -> ::sqlx::mysql::MySqlTypeInfo { - ::sqlx::mysql::MySqlTypeInfo::__enum() + impl ::#crate_name::Type<::#crate_name::MySql> for #ident { + fn type_info() -> ::#crate_name::mysql::MySqlTypeInfo { + ::#crate_name::mysql::MySqlTypeInfo::__enum() } } )); @@ -192,9 +195,9 @@ fn expand_derive_has_sql_type_strong_enum( tts.extend(quote!( #[automatically_derived] - impl ::sqlx::Type<::sqlx::Postgres> for #ident { - fn type_info() -> ::sqlx::postgres::PgTypeInfo { - ::sqlx::postgres::PgTypeInfo::with_name(#ty_name) + impl ::#crate_name::Type<::#crate_name::Postgres> for #ident { + fn type_info() -> ::#crate_name::postgres::PgTypeInfo { + ::#crate_name::postgres::PgTypeInfo::with_name(#ty_name) } } )); @@ -202,9 +205,9 @@ fn expand_derive_has_sql_type_strong_enum( if !attributes.no_pg_array { tts.extend(quote!( #[automatically_derived] - impl ::sqlx::postgres::PgHasArrayType for #ident { - fn array_type_info() -> ::sqlx::postgres::PgTypeInfo { - ::sqlx::postgres::PgTypeInfo::array_of(#ty_name) + impl ::#crate_name::postgres::PgHasArrayType for #ident { + fn array_type_info() -> ::#crate_name::postgres::PgTypeInfo { + ::#crate_name::postgres::PgTypeInfo::array_of(#ty_name) } } )); @@ -214,13 +217,13 @@ fn expand_derive_has_sql_type_strong_enum( if cfg!(feature = "_sqlite") { tts.extend(quote!( #[automatically_derived] - impl sqlx::Type<::sqlx::Sqlite> for #ident { - fn type_info() -> ::sqlx::sqlite::SqliteTypeInfo { - <::std::primitive::str as ::sqlx::Type>::type_info() + impl ::#crate_name::Type<::#crate_name::Sqlite> for #ident { + fn type_info() -> ::#crate_name::sqlite::SqliteTypeInfo { + <::std::primitive::str as ::#crate_name::Type<::#crate_name::Sqlite>>::type_info() } - fn compatible(ty: &::sqlx::sqlite::SqliteTypeInfo) -> ::std::primitive::bool { - <&::std::primitive::str as ::sqlx::types::Type>::compatible(ty) + fn compatible(ty: &::#crate_name::sqlite::SqliteTypeInfo) -> ::std::primitive::bool { + <&::std::primitive::str as ::#crate_name::types::Type<::#crate_name::sqlite::Sqlite>>::compatible(ty) } } )); @@ -232,6 +235,7 @@ fn expand_derive_has_sql_type_strong_enum( fn expand_derive_has_sql_type_struct( input: &DeriveInput, fields: &Punctuated, + crate_name: &Ident, ) -> syn::Result { let attributes = check_struct_attributes(input, fields)?; @@ -243,9 +247,9 @@ fn expand_derive_has_sql_type_struct( tts.extend(quote!( #[automatically_derived] - impl ::sqlx::Type<::sqlx::Postgres> for #ident { - fn type_info() -> ::sqlx::postgres::PgTypeInfo { - ::sqlx::postgres::PgTypeInfo::with_name(#ty_name) + impl ::#crate_name::Type<::#crate_name::Postgres> for #ident { + fn type_info() -> ::#crate_name::postgres::PgTypeInfo { + ::#crate_name::postgres::PgTypeInfo::with_name(#ty_name) } } )); @@ -253,9 +257,9 @@ fn expand_derive_has_sql_type_struct( if !attributes.no_pg_array { tts.extend(quote!( #[automatically_derived] - impl ::sqlx::postgres::PgHasArrayType for #ident { - fn array_type_info() -> ::sqlx::postgres::PgTypeInfo { - ::sqlx::postgres::PgTypeInfo::array_of(#ty_name) + impl ::#crate_name::postgres::PgHasArrayType for #ident { + fn array_type_info() -> ::#crate_name::postgres::PgTypeInfo { + ::#crate_name::postgres::PgTypeInfo::array_of(#ty_name) } } )); diff --git a/sqlx-macros-core/src/migrate.rs b/sqlx-macros-core/src/migrate.rs index b855703c22..576916e56d 100644 --- a/sqlx-macros-core/src/migrate.rs +++ b/sqlx-macros-core/src/migrate.rs @@ -7,19 +7,25 @@ use proc_macro2::{Span, TokenStream}; use quote::{quote, ToTokens, TokenStreamExt}; use sqlx_core::config::Config; use sqlx_core::migrate::{Migration, MigrationType}; -use syn::LitStr; +use syn::{Ident, LitStr}; pub const DEFAULT_PATH: &str = "./migrations"; -pub struct QuoteMigrationType(MigrationType); +pub struct QuoteMigrationType { + crate_name: Ident, + inner: MigrationType, +} impl ToTokens for QuoteMigrationType { fn to_tokens(&self, tokens: &mut TokenStream) { - let ts = match self.0 { - MigrationType::Simple => quote! { ::sqlx::migrate::MigrationType::Simple }, - MigrationType::ReversibleUp => quote! { ::sqlx::migrate::MigrationType::ReversibleUp }, + let crate_name = &self.crate_name; + let ts = match self.inner { + MigrationType::Simple => quote! { ::#crate_name::migrate::MigrationType::Simple }, + MigrationType::ReversibleUp => { + quote! { ::#crate_name::migrate::MigrationType::ReversibleUp } + } MigrationType::ReversibleDown => { - quote! { ::sqlx::migrate::MigrationType::ReversibleDown } + quote! { ::#crate_name::migrate::MigrationType::ReversibleDown } } }; tokens.append_all(ts); @@ -29,6 +35,7 @@ impl ToTokens for QuoteMigrationType { struct QuoteMigration { migration: Migration, path: PathBuf, + crate_name: Ident, } impl ToTokens for QuoteMigration { @@ -42,7 +49,12 @@ impl ToTokens for QuoteMigration { .. } = &self.migration; - let migration_type = QuoteMigrationType(*migration_type); + let crate_name = &self.crate_name; + + let migration_type = QuoteMigrationType { + inner: *migration_type, + crate_name: crate_name.clone(), + }; let sql = self .path @@ -67,11 +79,11 @@ impl ToTokens for QuoteMigration { .unwrap_or_else(|e| quote! { compile_error!(#e) }); let ts = quote! { - ::sqlx::migrate::Migration { + ::#crate_name::migrate::Migration { version: #version, description: ::std::borrow::Cow::Borrowed(#description), migration_type: #migration_type, - sql: ::sqlx::SqlStr::from_static(#sql), + sql: ::#crate_name::SqlStr::from_static(#sql), no_tx: #no_tx, checksum: ::std::borrow::Cow::Borrowed(&[ #(#checksum),* @@ -91,7 +103,7 @@ pub fn default_path(config: &Config) -> &str { .unwrap_or(DEFAULT_PATH) } -pub fn expand(path_arg: Option) -> crate::Result { +pub fn expand(path_arg: Option, crate_name: &Ident) -> crate::Result { let config = Config::try_from_crate_or_default()?; let path = match path_arg { @@ -99,10 +111,14 @@ pub fn expand(path_arg: Option) -> crate::Result { None => { crate::common::resolve_path(default_path(&config), Span::call_site()) }?, }; - expand_with_path(&config, &path) + expand_with_path(&config, &path, crate_name) } -pub fn expand_with_path(config: &Config, path: &Path) -> crate::Result { +pub fn expand_with_path( + config: &Config, + path: &Path, + crate_name: &Ident, +) -> crate::Result { let path = path.canonicalize().map_err(|e| { format!( "error canonicalizing migration directory {}: {e}", @@ -115,7 +131,11 @@ pub fn expand_with_path(config: &Config, path: &Path) -> crate::Result crate::Result( config: &Config, warnings: &mut Warnings, info: &Describe, + crate_name: &Ident, ) -> crate::Result { let db_path = DB::db_path(); if input.arg_exprs.is_empty() { return Ok(quote! { - let query_args = ::core::result::Result::<_, ::sqlx::error::BoxDynError>::Ok(<#db_path as ::sqlx::database::Database>::Arguments::<'_>::default()); + let query_args = ::core::result::Result::<_, ::#crate_name::error::BoxDynError>::Ok(<#db_path as ::#crate_name::database::Database>::Arguments::<'_>::default()); }); } @@ -64,18 +65,18 @@ pub fn quote_args( Ok(quote_spanned!(expr.span() => // this shouldn't actually run - #[allow(clippy::missing_panics_doc, clippy::unreachable)] + #[allow(clippy::missing_panics_doc, clippy::unreachable, unused_mut)] if false { - use ::sqlx::ty_match::{WrapSameExt as _, MatchBorrowExt as _}; + use ::#crate_name::ty_match::{WrapSameExt as _, MatchBorrowExt as _}; // evaluate the expression only once in case it contains moves - let expr = ::sqlx::ty_match::dupe_value(#name); + let expr = ::#crate_name::ty_match::dupe_value(#name); // if `expr` is `Option`, get `Option<$ty>`, otherwise `$ty` - let ty_check = ::sqlx::ty_match::WrapSame::<#param_ty, _>::new(&expr).wrap_same(); + let ty_check = ::#crate_name::ty_match::WrapSame::<#param_ty, _>::new(&expr).wrap_same(); // if `expr` is `&str`, convert `String` to `&str` - let (mut _ty_check, match_borrow) = ::sqlx::ty_match::MatchBorrow::new(ty_check, &expr); + let (mut _ty_check, mut match_borrow) = ::#crate_name::ty_match::MatchBorrow::new(ty_check, &expr); _ty_check = match_borrow.match_borrow(); @@ -95,12 +96,12 @@ pub fn quote_args( #args_check - let mut query_args = <#db_path as ::sqlx::database::Database>::Arguments::<'_>::default(); + let mut query_args = <#db_path as ::#crate_name::database::Database>::Arguments::<'_>::default(); query_args.reserve( #args_count, - 0 #(+ ::sqlx::encode::Encode::<#db_path>::size_hint(#arg_name))* + 0 #(+ ::#crate_name::encode::Encode::<#db_path>::size_hint(#arg_name))* ); - let query_args = ::core::result::Result::<_, ::sqlx::error::BoxDynError>::Ok(query_args) + let query_args = ::core::result::Result::<_, ::#crate_name::error::BoxDynError>::Ok(query_args) #(.and_then(move |mut query_args| query_args.add(#arg_name).map(move |()| query_args) ))*; }) } diff --git a/sqlx-macros-core/src/query/mod.rs b/sqlx-macros-core/src/query/mod.rs index ea454737c1..111f445474 100644 --- a/sqlx-macros-core/src/query/mod.rs +++ b/sqlx-macros-core/src/query/mod.rs @@ -4,7 +4,7 @@ use std::sync::{Arc, LazyLock, Mutex}; use std::{fs, io}; use proc_macro2::TokenStream; -use syn::Type; +use syn::{Ident, Type}; pub use input::QueryMacroInput; use quote::{format_ident, quote}; @@ -27,7 +27,7 @@ mod output; pub struct QueryDriver { db_name: &'static str, url_schemes: &'static [&'static str], - expand: fn(&Config, QueryMacroInput, QueryDataSource) -> crate::Result, + expand: fn(&Config, QueryMacroInput, QueryDataSource, Ident) -> crate::Result, } impl QueryDriver { @@ -141,6 +141,7 @@ fn init_metadata(manifest_dir: &String) -> crate::Result { pub fn expand_input<'a>( input: QueryMacroInput, drivers: impl IntoIterator, + crate_name: Ident, ) -> crate::Result { let manifest_dir = env("CARGO_MANIFEST_DIR").expect("`CARGO_MANIFEST_DIR` must be set"); @@ -197,7 +198,7 @@ pub fn expand_input<'a>( for driver in drivers { if data_source.matches_driver(driver) { - return (driver.expand)(&metadata.config, input, data_source); + return (driver.expand)(&metadata.config, input, data_source, crate_name); } } @@ -222,6 +223,7 @@ fn expand_with( config: &Config, input: QueryMacroInput, data_source: QueryDataSource, + crate_name: Ident, ) -> crate::Result where Describe: DescribeExt, @@ -234,7 +236,7 @@ where } }; - expand_with_data(config, input, query_data, offline) + expand_with_data(config, input, query_data, offline, crate_name) } // marker trait for `Describe` that lets us conditionally require it to be `Serialize + Deserialize` @@ -256,6 +258,7 @@ fn expand_with_data( input: QueryMacroInput, data: QueryData, offline: bool, + crate_name: Ident, ) -> crate::Result where Describe: DescribeExt, @@ -278,7 +281,7 @@ where let mut warnings = Warnings::default(); - let args_tokens = args::quote_args(&input, config, &mut warnings, &data.describe)?; + let args_tokens = args::quote_args(&input, config, &mut warnings, &data.describe, &crate_name)?; let query_args = format_ident!("query_args"); @@ -292,7 +295,7 @@ where let sql = &input.sql; quote! { - ::sqlx::__query_with_result::<#db_path, _>(#sql, #query_args) + ::#crate_name::__query_with_result::<#db_path, _>(#sql, #query_args) } } else { match input.record_type { @@ -328,6 +331,7 @@ where &record_name, &query_args, &columns, + &crate_name, )); record_tokens @@ -335,7 +339,7 @@ where RecordType::Given(ref out_ty) => { let columns = output::columns_to_rust::(&data.describe, config, &mut warnings)?; - output::quote_query_as::(&input, out_ty, &query_args, &columns) + output::quote_query_as::(&input, out_ty, &query_args, &columns, &crate_name) } RecordType::Scalar => output::quote_query_scalar::( &input, @@ -343,6 +347,7 @@ where &mut warnings, &query_args, &data.describe, + &crate_name, )?, } }; @@ -352,14 +357,14 @@ where if warnings.ambiguous_datetime { // Warns if the date-time crate is inferred but both `chrono` and `time` are enabled warnings_out.extend(quote! { - ::sqlx::warn_on_ambiguous_inferred_date_time_crate(); + ::#crate_name::warn_on_ambiguous_inferred_date_time_crate(); }); } if warnings.ambiguous_numeric { // Warns if the numeric crate is inferred but both `bigdecimal` and `rust_decimal` are enabled warnings_out.extend(quote! { - ::sqlx::warn_on_ambiguous_inferred_numeric_crate(); + ::#crate_name::warn_on_ambiguous_inferred_numeric_crate(); }); } @@ -367,7 +372,7 @@ where { #[allow(clippy::all)] { - use ::sqlx::Arguments as _; + use ::#crate_name::Arguments as _; #warnings_out diff --git a/sqlx-macros-core/src/query/output.rs b/sqlx-macros-core/src/query/output.rs index 987dcaa3cb..7f1e5089b9 100644 --- a/sqlx-macros-core/src/query/output.rs +++ b/sqlx-macros-core/src/query/output.rs @@ -141,6 +141,7 @@ pub fn quote_query_as( out_ty: &Type, bind_args: &Ident, columns: &[RustColumn], + crate_name: &Ident, ) -> TokenStream { let instantiations = columns.iter().enumerate().map( |( @@ -193,8 +194,8 @@ pub fn quote_query_as( }; quote! { - ::sqlx::__query_with_result::<#db_path, _>(#sql, #bind_args).try_map(|row: #row_path| { - use ::sqlx::Row as _; + ::#crate_name::__query_with_result::<#db_path, _>(#sql, #bind_args).try_map(|row: #row_path| { + use ::#crate_name::Row as _; #(#instantiations)* @@ -209,6 +210,7 @@ pub fn quote_query_scalar( warnings: &mut Warnings, bind_args: &Ident, describe: &Describe, + crate_name: &Ident, ) -> crate::Result { let columns = describe.columns(); @@ -238,7 +240,7 @@ pub fn quote_query_scalar( let query = &input.sql; Ok(quote! { - ::sqlx::__query_scalar_with_result::<#db, #ty, _>(#query, #bind_args) + ::#crate_name::__query_scalar_with_result::<#db, #ty, _>(#query, #bind_args) }) } diff --git a/sqlx-macros-core/src/test_attr.rs b/sqlx-macros-core/src/test_attr.rs index 046ff5c2fb..3b095be1d7 100644 --- a/sqlx-macros-core/src/test_attr.rs +++ b/sqlx-macros-core/src/test_attr.rs @@ -1,6 +1,6 @@ use proc_macro2::TokenStream; use quote::quote; -use syn::parse::Parser; +use syn::{parse::Parser, Ident}; #[cfg(feature = "migrate")] struct Args { @@ -26,7 +26,11 @@ enum MigrationsOpt { type AttributeArgs = syn::punctuated::Punctuated; -pub fn expand(args: TokenStream, input: syn::ItemFn) -> crate::Result { +pub fn expand( + args: TokenStream, + input: syn::ItemFn, + crate_name: Ident, +) -> crate::Result { let parser = AttributeArgs::parse_terminated; let args = parser.parse2(args)?; @@ -50,17 +54,17 @@ pub fn expand(args: TokenStream, input: syn::ItemFn) -> crate::Result TokenStream { +fn expand_simple(input: syn::ItemFn, crate_name: Ident) -> TokenStream { let ret = &input.sig.output; let name = &input.sig.ident; let body = &input.block; @@ -70,13 +74,17 @@ fn expand_simple(input: syn::ItemFn) -> TokenStream { #[::core::prelude::v1::test] #(#attrs)* fn #name() #ret { - ::sqlx::test_block_on(async { #body }) + ::#crate_name::test_block_on(async { #body }) } } } #[cfg(feature = "migrate")] -fn expand_advanced(args: AttributeArgs, input: syn::ItemFn) -> crate::Result { +fn expand_advanced( + args: AttributeArgs, + input: syn::ItemFn, + crate_name: Ident, +) -> crate::Result { let config = sqlx_core::config::Config::try_from_crate_or_default()?; let ret = &input.sig.output; @@ -103,7 +111,7 @@ fn expand_advanced(args: AttributeArgs, input: syn::ItemFn) -> crate::Result crate::Result crate::Result crate::Result { - let migrator = crate::migrate::expand(Some(path))?; + let migrator = crate::migrate::expand(Some(path), &crate_name)?; quote! { args.migrator(&#migrator); } } MigrationsOpt::InferredPath if !inputs.is_empty() => { @@ -154,7 +162,8 @@ fn expand_advanced(args: AttributeArgs, input: syn::ItemFn) -> crate::Result crate::Result crate::Result _ = #name; - ::sqlx::testing::TestFn::run_test(f, args) + ::#crate_name::testing::TestFn::run_test(f, args) } }) } diff --git a/sqlx-macros/Cargo.toml b/sqlx-macros/Cargo.toml index 1c3cd96bff..8cfc77f818 100644 --- a/sqlx-macros/Cargo.toml +++ b/sqlx-macros/Cargo.toml @@ -21,7 +21,9 @@ _rt-tokio = ["sqlx-macros-core/_rt-tokio"] _tls-native-tls = ["sqlx-macros-core/_tls-native-tls"] _tls-rustls-aws-lc-rs = ["sqlx-macros-core/_tls-rustls-aws-lc-rs"] _tls-rustls-ring-webpki = ["sqlx-macros-core/_tls-rustls-ring-webpki"] -_tls-rustls-ring-native-roots = ["sqlx-macros-core/_tls-rustls-ring-native-roots"] +_tls-rustls-ring-native-roots = [ + "sqlx-macros-core/_tls-rustls-ring-native-roots", +] # SQLx features derive = ["sqlx-macros-core/derive"] @@ -55,8 +57,18 @@ sqlx-core = { workspace = true, features = ["any"] } sqlx-macros-core = { workspace = true } proc-macro2 = { version = "1.0.36", default-features = false } -syn = { version = "2.0.52", default-features = false, features = ["parsing", "proc-macro"] } +syn = { version = "2.0.52", default-features = false, features = [ + "parsing", + "proc-macro", +] } quote = { version = "1.0.26", default-features = false } +[dev-dependencies] +sqlx = { workspace = true, features = ["derive", "macros", "migrate", "postgres"] } + +[[test]] +name = "macros_namespace" +path = "tests/macros_namespace.rs" + [lints] -workspace = true +workspace = true \ No newline at end of file diff --git a/sqlx-macros/build.rs b/sqlx-macros/build.rs new file mode 100644 index 0000000000..d05e0a6be4 --- /dev/null +++ b/sqlx-macros/build.rs @@ -0,0 +1,4 @@ +fn main() { + println!("cargo::rustc-check-cfg=cfg(sqlx_macros_namespace)"); + println!("cargo:rerun-if-env-changed=SQLX_NAMESPACE"); +} diff --git a/sqlx-macros/src/lib.rs b/sqlx-macros/src/lib.rs index ccffc9bd2a..3313f0a808 100644 --- a/sqlx-macros/src/lib.rs +++ b/sqlx-macros/src/lib.rs @@ -4,12 +4,22 @@ use quote::quote; use sqlx_macros_core::*; +/// Constant used in all macros to define the macros namespace. +/// This accommodates 3rd party drivers by allowing them to specify a different +/// root crate that paths used with proc macros resolve to. +#[cfg(not(sqlx_macros_namespace))] +const CRATE_NAME: &str = "sqlx"; +// Allows for easier testing of the configurable macros namespace feature +// of current proc macros without duplicating them. +#[cfg(sqlx_macros_namespace)] +const CRATE_NAME: &str = env!("SQLX_NAMESPACE"); + #[cfg(feature = "macros")] #[proc_macro] pub fn expand_query(input: TokenStream) -> TokenStream { let input = syn::parse_macro_input!(input as query::QueryMacroInput); - match query::expand_input(input, FOSS_DRIVERS) { + match query::expand_input(input, FOSS_DRIVERS, quote::format_ident!("{CRATE_NAME}")) { Ok(ts) => ts.into(), Err(e) => { if let Some(parse_err) = e.downcast_ref::() { @@ -26,7 +36,7 @@ pub fn expand_query(input: TokenStream) -> TokenStream { #[proc_macro_derive(Encode, attributes(sqlx))] pub fn derive_encode(tokenstream: TokenStream) -> TokenStream { let input = syn::parse_macro_input!(tokenstream as syn::DeriveInput); - match derives::expand_derive_encode(&input) { + match derives::expand_derive_encode(&input, "e::format_ident!("{CRATE_NAME}")) { Ok(ts) => ts.into(), Err(e) => e.to_compile_error().into(), } @@ -36,7 +46,7 @@ pub fn derive_encode(tokenstream: TokenStream) -> TokenStream { #[proc_macro_derive(Decode, attributes(sqlx))] pub fn derive_decode(tokenstream: TokenStream) -> TokenStream { let input = syn::parse_macro_input!(tokenstream as syn::DeriveInput); - match derives::expand_derive_decode(&input) { + match derives::expand_derive_decode(&input, "e::format_ident!("{CRATE_NAME}")) { Ok(ts) => ts.into(), Err(e) => e.to_compile_error().into(), } @@ -46,7 +56,7 @@ pub fn derive_decode(tokenstream: TokenStream) -> TokenStream { #[proc_macro_derive(Type, attributes(sqlx))] pub fn derive_type(tokenstream: TokenStream) -> TokenStream { let input = syn::parse_macro_input!(tokenstream as syn::DeriveInput); - match derives::expand_derive_type_encode_decode(&input) { + match derives::expand_derive_type_encode_decode(&input, quote::format_ident!("{CRATE_NAME}")) { Ok(ts) => ts.into(), Err(e) => e.to_compile_error().into(), } @@ -57,7 +67,7 @@ pub fn derive_type(tokenstream: TokenStream) -> TokenStream { pub fn derive_from_row(input: TokenStream) -> TokenStream { let input = syn::parse_macro_input!(input as syn::DeriveInput); - match derives::expand_derive_from_row(&input) { + match derives::expand_derive_from_row(&input, quote::format_ident!("{CRATE_NAME}")) { Ok(ts) => ts.into(), Err(e) => e.to_compile_error().into(), } @@ -69,7 +79,7 @@ pub fn migrate(input: TokenStream) -> TokenStream { use syn::LitStr; let input = syn::parse_macro_input!(input as Option); - match migrate::expand(input) { + match migrate::expand(input, "e::format_ident!("{CRATE_NAME}")) { Ok(ts) => ts.into(), Err(e) => { if let Some(parse_err) = e.downcast_ref::() { @@ -87,7 +97,7 @@ pub fn migrate(input: TokenStream) -> TokenStream { pub fn test(args: TokenStream, input: TokenStream) -> TokenStream { let input = syn::parse_macro_input!(input as syn::ItemFn); - match test_attr::expand(args.into(), input) { + match test_attr::expand(args.into(), input, quote::format_ident!("{CRATE_NAME}")) { Ok(ts) => ts.into(), Err(e) => { if let Some(parse_err) = e.downcast_ref::() { diff --git a/sqlx-macros/tests/macros_namespace.rs b/sqlx-macros/tests/macros_namespace.rs new file mode 100644 index 0000000000..39bca3e83c --- /dev/null +++ b/sqlx-macros/tests/macros_namespace.rs @@ -0,0 +1,20 @@ +/// Import as different namespace. +/// +/// This must be set as `SQLX_NAMESPACE` environment variable to test that +/// changing the namespace still results in the proc macros behaving well. +extern crate sqlx as external; + +#[test] +#[cfg(feature = "migrate")] +fn test_macros_namespace_migrate() { + let _ = external::migrate!("../tests/migrate/migrations_simple"); +} + +#[test] +#[cfg(feature = "derive")] +fn test_macros_namespace_derive() { + #[derive(Debug, external::Type, external::FromRow)] + struct Test { + value: i32, + } +}