From 315882ce47d81effcfcfe2b32398ec838084ec02 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 22 Jul 2025 01:49:55 +0300 Subject: [PATCH 1/5] introduce a crate_name argument in proc_macros core --- sqlx-macros-core/src/derives/decode.rs | 71 ++++++++++---------- sqlx-macros-core/src/derives/encode.rs | 73 ++++++++++---------- sqlx-macros-core/src/derives/mod.rs | 10 +-- sqlx-macros-core/src/derives/row.rs | 81 ++++++++++++----------- sqlx-macros-core/src/derives/type.rs | 92 ++++++++++++++------------ sqlx-macros-core/src/migrate.rs | 50 +++++++++----- sqlx-macros-core/src/query/args.rs | 19 +++--- sqlx-macros-core/src/query/mod.rs | 25 ++++--- sqlx-macros-core/src/query/output.rs | 8 ++- sqlx-macros-core/src/test_attr.rs | 28 ++++---- sqlx-macros/src/lib.rs | 27 ++++++-- 11 files changed, 268 insertions(+), 216 deletions(-) diff --git a/sqlx-macros-core/src/derives/decode.rs b/sqlx-macros-core/src/derives/decode.rs index 7af9643d93..cc41bf10ac 100644 --- a/sqlx-macros-core/src/derives/decode.rs +++ b/sqlx-macros-core/src/derives/decode.rs @@ -8,27 +8,26 @@ use quote::quote; use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{ - parse_quote, Arm, Data, DataEnum, DataStruct, DeriveInput, Field, Fields, FieldsNamed, - FieldsUnnamed, Stmt, TypeParamBound, Variant, + parse_quote, Arm, Data, DataEnum, DataStruct, DeriveInput, Field, Fields, FieldsNamed, 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 +49,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 +64,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 +94,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 +114,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 +142,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 +178,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 +190,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 +204,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 +216,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 +230,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 +242,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 +259,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 +275,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 +297,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 +311,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..961c40bf46 100644 --- a/sqlx-macros-core/src/derives/encode.rs +++ b/sqlx-macros-core/src/derives/encode.rs @@ -8,11 +8,10 @@ use quote::quote; 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, + parse_quote, Data, DataEnum, DataStruct, DeriveInput, Expr, Field, Fields, FieldsNamed, 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 +19,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 +50,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 +70,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 +103,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 +118,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 +143,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 +169,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 +189,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 +198,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 +215,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 +237,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..96e101506a 100644 --- a/sqlx-macros-core/src/derives/mod.rs +++ b/sqlx-macros-core/src/derives/mod.rs @@ -12,12 +12,12 @@ 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..71fd094a9a 100644 --- a/sqlx-macros-core/src/derives/row.rs +++ b/sqlx-macros-core/src/derives/row.rs @@ -1,8 +1,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, + parse_quote, punctuated::Punctuated, token::Comma, Data, DataStruct, DeriveInput, Expr, Field, Fields, FieldsNamed, FieldsUnnamed, Ident, Lifetime, Stmt }; use super::{ @@ -10,17 +9,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 +38,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 +53,7 @@ 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 +61,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 +101,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 +136,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 +146,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 +157,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 +182,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 +208,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 +228,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 +245,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 +260,7 @@ 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 +269,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 +288,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..319e384ff4 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()); }); } @@ -66,16 +67,16 @@ pub fn quote_args( // this shouldn't actually run #[allow(clippy::missing_panics_doc, clippy::unreachable)] 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..da3cf027ae 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..85746ec0d1 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..d648386907 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,7 @@ 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 +50,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 +70,13 @@ 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 +103,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 +154,7 @@ 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/src/lib.rs b/sqlx-macros/src/lib.rs index ccffc9bd2a..0e71b11988 100644 --- a/sqlx-macros/src/lib.rs +++ b/sqlx-macros/src/lib.rs @@ -4,12 +4,25 @@ use quote::quote; use sqlx_macros_core::*; +/// Constant used in all macros to define the root crate. +/// This accommodates 3rd party drivers by allowing them to specify a different +/// root crate that paths used with proc macros resolve to. +#[cfg(not(test))] +const CRATE_NAME: &str = "sqlx"; +// Allows for easier testing of the configurable root crate feature +// of current proc macros without duplicating them. +#[cfg(test)] +const CRATE_NAME: &str = match option_env!("SQLX_ROOT_CRATE") { + Some(c) => c, + None => "sqlx", +}; + #[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 +39,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 +49,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 +59,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 +70,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 +82,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 +100,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::() { From c7b634ccfc3e9872a581a0c70278e36cc7d96858 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 22 Jul 2025 16:07:04 +0300 Subject: [PATCH 2/5] add macros namespace test --- .github/workflows/sqlx.yml | 15 +++++++++++++++ Cargo.lock | 1 + sqlx-macros/Cargo.toml | 14 +++++++++++--- sqlx-macros/src/lib.rs | 37 +++++++++++++++++++++++++++++++------ 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/.github/workflows/sqlx.yml b/.github/workflows/sqlx.yml index 4b080b42d2..69ab6778db 100644 --- a/.github/workflows/sqlx.yml +++ b/.github/workflows/sqlx.yml @@ -104,6 +104,21 @@ jobs: cargo test -p sqlx-macros-core --all-features + + - name: Test sqlx-macros custom namespace + run: > + SQLX_NAMESPACE="external" + cargo test + -p sqlx-macros + --all-features + + # Should fail compilation since the env var is not set + # and the testing `_macros-namespace` feature is enabled. + - name: Test sqlx-macros without namespace + run: > + cargo test + -p sqlx-macros + --all-features || true # 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/Cargo.toml b/sqlx-macros/Cargo.toml index 1c3cd96bff..26dd44e3a7 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,14 @@ 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"] } + [lints] -workspace = true +workspace = true \ No newline at end of file diff --git a/sqlx-macros/src/lib.rs b/sqlx-macros/src/lib.rs index 0e71b11988..bfa2c35d2c 100644 --- a/sqlx-macros/src/lib.rs +++ b/sqlx-macros/src/lib.rs @@ -4,18 +4,15 @@ use quote::quote; use sqlx_macros_core::*; -/// Constant used in all macros to define the root crate. +/// 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(test))] const CRATE_NAME: &str = "sqlx"; -// Allows for easier testing of the configurable root crate feature +// Allows for easier testing of the configurable macros namespace feature // of current proc macros without duplicating them. #[cfg(test)] -const CRATE_NAME: &str = match option_env!("SQLX_ROOT_CRATE") { - Some(c) => c, - None => "sqlx", -}; +const CRATE_NAME: &str = env!("SQLX_NAMESPACE"); #[cfg(feature = "macros")] #[proc_macro] @@ -112,3 +109,31 @@ pub fn test(args: TokenStream, input: TokenStream) -> TokenStream { } } } + +#[cfg(test)] +mod tests { + #[test] + #[cfg(feature = "migrate")] + fn test_macros_namespace_migrate() { + /// 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; + + let _ = external::migrate!("../tests/migrate/migrations_simple"); + } + + #[test] + #[cfg(feature = "derive")] + fn test_macros_namespace_derive() { + /// 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; + + #[derive(Debug, external::Type, external::Encode, external::Decode, external::FromRow)] + struct Test {} + } +} From 4472e9d7bc77eb21c36069f7a1cb0373f540f11d Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 22 Jul 2025 17:03:12 +0300 Subject: [PATCH 3/5] formatting --- sqlx-macros-core/src/derives/decode.rs | 9 +++++---- sqlx-macros-core/src/derives/encode.rs | 7 ++++--- sqlx-macros-core/src/derives/mod.rs | 5 ++++- sqlx-macros-core/src/derives/row.rs | 15 ++++++++++----- sqlx-macros-core/src/derives/type.rs | 6 +++--- sqlx-macros-core/src/query/args.rs | 2 +- sqlx-macros-core/src/query/mod.rs | 6 +++--- sqlx-macros-core/src/query/output.rs | 2 +- sqlx-macros-core/src/test_attr.rs | 15 ++++++++++++--- sqlx-macros/src/lib.rs | 2 +- 10 files changed, 44 insertions(+), 25 deletions(-) diff --git a/sqlx-macros-core/src/derives/decode.rs b/sqlx-macros-core/src/derives/decode.rs index cc41bf10ac..6b1579df13 100644 --- a/sqlx-macros-core/src/derives/decode.rs +++ b/sqlx-macros-core/src/derives/decode.rs @@ -8,7 +8,8 @@ use quote::quote; use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{ - parse_quote, Arm, Data, DataEnum, DataStruct, DeriveInput, Field, Fields, FieldsNamed, FieldsUnnamed, Ident, Stmt, TypeParamBound, Variant + parse_quote, Arm, Data, DataEnum, DataStruct, DeriveInput, Field, Fields, FieldsNamed, + FieldsUnnamed, Ident, Stmt, TypeParamBound, Variant, }; pub fn expand_derive_decode(input: &DeriveInput, crate_name: &Ident) -> syn::Result { @@ -49,7 +50,7 @@ pub fn expand_derive_decode(input: &DeriveInput, crate_name: &Ident) -> syn::Res fn expand_derive_decode_transparent( input: &DeriveInput, field: &Field, - crate_name: &Ident + crate_name: &Ident, ) -> syn::Result { check_transparent_attributes(input, field)?; @@ -142,7 +143,7 @@ fn expand_derive_decode_weak_enum( fn expand_derive_decode_strong_enum( input: &DeriveInput, variants: &Punctuated, - crate_name: &Ident + crate_name: &Ident, ) -> syn::Result { let cattr = check_strong_enum_attributes(input, variants)?; @@ -259,7 +260,7 @@ fn expand_derive_decode_strong_enum( fn expand_derive_decode_struct( input: &DeriveInput, fields: &Punctuated, - crate_name: &Ident + crate_name: &Ident, ) -> syn::Result { check_struct_attributes(input, fields)?; diff --git a/sqlx-macros-core/src/derives/encode.rs b/sqlx-macros-core/src/derives/encode.rs index 961c40bf46..25f2279d5d 100644 --- a/sqlx-macros-core/src/derives/encode.rs +++ b/sqlx-macros-core/src/derives/encode.rs @@ -8,7 +8,8 @@ use quote::quote; use syn::punctuated::Punctuated; use syn::token::Comma; use syn::{ - parse_quote, Data, DataEnum, DataStruct, DeriveInput, Expr, Field, Fields, FieldsNamed, FieldsUnnamed, Ident, Lifetime, LifetimeParam, Stmt, TypeParamBound, Variant + parse_quote, Data, DataEnum, DataStruct, DeriveInput, Expr, Field, Fields, FieldsNamed, + FieldsUnnamed, Ident, Lifetime, LifetimeParam, Stmt, TypeParamBound, Variant, }; pub fn expand_derive_encode(input: &DeriveInput, crate_name: &Ident) -> syn::Result { @@ -143,7 +144,7 @@ fn expand_derive_encode_weak_enum( fn expand_derive_encode_strong_enum( input: &DeriveInput, variants: &Punctuated, - crate_name: &Ident + crate_name: &Ident, ) -> syn::Result { let cattr = check_strong_enum_attributes(input, variants)?; @@ -198,7 +199,7 @@ fn expand_derive_encode_strong_enum( fn expand_derive_encode_struct( input: &DeriveInput, fields: &Punctuated, - crate_name: &Ident + crate_name: &Ident, ) -> syn::Result { check_struct_attributes(input, fields)?; diff --git a/sqlx-macros-core/src/derives/mod.rs b/sqlx-macros-core/src/derives/mod.rs index 96e101506a..8867a299f0 100644 --- a/sqlx-macros-core/src/derives/mod.rs +++ b/sqlx-macros-core/src/derives/mod.rs @@ -14,7 +14,10 @@ use heck::{ToKebabCase, ToLowerCamelCase, ToShoutySnakeCase, ToSnakeCase, ToUppe use proc_macro2::TokenStream; use syn::{DeriveInput, Ident}; -pub fn expand_derive_type_encode_decode(input: &DeriveInput, crate_name: Ident) -> syn::Result { +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)?; diff --git a/sqlx-macros-core/src/derives/row.rs b/sqlx-macros-core/src/derives/row.rs index 71fd094a9a..dce7c187b4 100644 --- a/sqlx-macros-core/src/derives/row.rs +++ b/sqlx-macros-core/src/derives/row.rs @@ -1,7 +1,8 @@ use proc_macro2::{Span, TokenStream}; use quote::quote; use syn::{ - parse_quote, punctuated::Punctuated, token::Comma, Data, DataStruct, DeriveInput, Expr, Field, Fields, FieldsNamed, FieldsUnnamed, Ident, Lifetime, Stmt + parse_quote, punctuated::Punctuated, token::Comma, Data, DataStruct, DeriveInput, Expr, Field, + Fields, FieldsNamed, FieldsUnnamed, Ident, Lifetime, Stmt, }; use super::{ @@ -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: ::#crate_name::Row)); + generics + .params + .insert(0, parse_quote!(R: ::#crate_name::Row)); if provided { generics.params.insert(0, parse_quote!(#lifetime)); @@ -137,7 +140,7 @@ fn expand_derive_from_row_struct( (false, Some(try_from), None) => { predicates .push(parse_quote!(#try_from: ::#crate_name::decode::Decode<#lifetime, R::Database>)); - predicates.push(parse_quote!(#try_from: ::#crate_name::types::Type)); + predicates.push(parse_quote!(#try_from: ::#crate_name::types::Type)); parse_quote!( __row.try_get(#id_s) @@ -245,7 +248,7 @@ fn expand_derive_from_row_struct( fn expand_derive_from_row_struct_unnamed( input: &DeriveInput, fields: &Punctuated, - crate_name: Ident + crate_name: Ident, ) -> syn::Result { let ident = &input.ident; @@ -260,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: ::#crate_name::Row)); + generics + .params + .insert(0, parse_quote!(R: ::#crate_name::Row)); if provided { generics.params.insert(0, parse_quote!(#lifetime)); diff --git a/sqlx-macros-core/src/derives/type.rs b/sqlx-macros-core/src/derives/type.rs index 319e384ff4..cd5df659cd 100644 --- a/sqlx-macros-core/src/derives/type.rs +++ b/sqlx-macros-core/src/derives/type.rs @@ -134,7 +134,7 @@ fn expand_derive_has_sql_type_transparent( fn expand_derive_has_sql_type_weak_enum( input: &DeriveInput, variants: &Punctuated, - crate_name: &Ident + crate_name: &Ident, ) -> syn::Result { let attrs = check_weak_enum_attributes(input, variants)?; let repr = attrs.repr.unwrap(); @@ -172,7 +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 + crate_name: &Ident, ) -> syn::Result { let attributes = check_strong_enum_attributes(input, variants)?; @@ -235,7 +235,7 @@ fn expand_derive_has_sql_type_strong_enum( fn expand_derive_has_sql_type_struct( input: &DeriveInput, fields: &Punctuated, - crate_name: &Ident + crate_name: &Ident, ) -> syn::Result { let attributes = check_struct_attributes(input, fields)?; diff --git a/sqlx-macros-core/src/query/args.rs b/sqlx-macros-core/src/query/args.rs index f09f9bfa29..4b3af4ed38 100644 --- a/sqlx-macros-core/src/query/args.rs +++ b/sqlx-macros-core/src/query/args.rs @@ -17,7 +17,7 @@ pub fn quote_args( config: &Config, warnings: &mut Warnings, info: &Describe, - crate_name: &Ident + crate_name: &Ident, ) -> crate::Result { let db_path = DB::db_path(); diff --git a/sqlx-macros-core/src/query/mod.rs b/sqlx-macros-core/src/query/mod.rs index da3cf027ae..111f445474 100644 --- a/sqlx-macros-core/src/query/mod.rs +++ b/sqlx-macros-core/src/query/mod.rs @@ -223,7 +223,7 @@ fn expand_with( config: &Config, input: QueryMacroInput, data_source: QueryDataSource, - crate_name: Ident + crate_name: Ident, ) -> crate::Result where Describe: DescribeExt, @@ -331,7 +331,7 @@ where &record_name, &query_args, &columns, - &crate_name + &crate_name, )); record_tokens @@ -347,7 +347,7 @@ where &mut warnings, &query_args, &data.describe, - &crate_name + &crate_name, )?, } }; diff --git a/sqlx-macros-core/src/query/output.rs b/sqlx-macros-core/src/query/output.rs index 85746ec0d1..7f1e5089b9 100644 --- a/sqlx-macros-core/src/query/output.rs +++ b/sqlx-macros-core/src/query/output.rs @@ -141,7 +141,7 @@ pub fn quote_query_as( out_ty: &Type, bind_args: &Ident, columns: &[RustColumn], - crate_name: &Ident + crate_name: &Ident, ) -> TokenStream { let instantiations = columns.iter().enumerate().map( |( diff --git a/sqlx-macros-core/src/test_attr.rs b/sqlx-macros-core/src/test_attr.rs index d648386907..3b095be1d7 100644 --- a/sqlx-macros-core/src/test_attr.rs +++ b/sqlx-macros-core/src/test_attr.rs @@ -26,7 +26,11 @@ enum MigrationsOpt { type AttributeArgs = syn::punctuated::Punctuated; -pub fn expand(args: TokenStream, input: syn::ItemFn, crate_name: Ident) -> 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)?; @@ -76,7 +80,11 @@ fn expand_simple(input: syn::ItemFn, crate_name: Ident) -> TokenStream { } #[cfg(feature = "migrate")] -fn expand_advanced(args: AttributeArgs, input: syn::ItemFn, crate_name: Ident) -> 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; @@ -154,7 +162,8 @@ fn expand_advanced(args: AttributeArgs, input: syn::ItemFn, crate_name: Ident) - let resolved_path = crate::common::resolve_path(path, proc_macro2::Span::call_site())?; if resolved_path.is_dir() { - let migrator = crate::migrate::expand_with_path(&config, &resolved_path, &crate_name)?; + let migrator = + crate::migrate::expand_with_path(&config, &resolved_path, &crate_name)?; quote! { args.migrator(&#migrator); } } else { quote! {} diff --git a/sqlx-macros/src/lib.rs b/sqlx-macros/src/lib.rs index bfa2c35d2c..2d5afada22 100644 --- a/sqlx-macros/src/lib.rs +++ b/sqlx-macros/src/lib.rs @@ -132,7 +132,7 @@ mod tests { /// 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; - + #[derive(Debug, external::Type, external::Encode, external::Decode, external::FromRow)] struct Test {} } From 5a24918ed6d482985c4a1fa79fbf79862f307ef8 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 22 Jul 2025 17:48:31 +0300 Subject: [PATCH 4/5] add build.rs watching; use internal cfg for testing --- .github/workflows/sqlx.yml | 8 +++++-- sqlx-macros/Cargo.toml | 6 ++++- sqlx-macros/build.rs | 4 ++++ sqlx-macros/src/lib.rs | 32 ++------------------------- sqlx-macros/tests/macros_namespace.rs | 20 +++++++++++++++++ 5 files changed, 37 insertions(+), 33 deletions(-) create mode 100644 sqlx-macros/build.rs create mode 100644 sqlx-macros/tests/macros_namespace.rs diff --git a/.github/workflows/sqlx.yml b/.github/workflows/sqlx.yml index 69ab6778db..b9b5251ccb 100644 --- a/.github/workflows/sqlx.yml +++ b/.github/workflows/sqlx.yml @@ -107,18 +107,22 @@ jobs: - name: Test sqlx-macros custom namespace run: > - SQLX_NAMESPACE="external" 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 `_macros-namespace` feature is enabled. + # 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/sqlx-macros/Cargo.toml b/sqlx-macros/Cargo.toml index 26dd44e3a7..8cfc77f818 100644 --- a/sqlx-macros/Cargo.toml +++ b/sqlx-macros/Cargo.toml @@ -64,7 +64,11 @@ syn = { version = "2.0.52", default-features = false, features = [ quote = { version = "1.0.26", default-features = false } [dev-dependencies] -sqlx = { workspace = true, features = ["derive", "macros", "migrate"] } +sqlx = { workspace = true, features = ["derive", "macros", "migrate", "postgres"] } + +[[test]] +name = "macros_namespace" +path = "tests/macros_namespace.rs" [lints] 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 2d5afada22..3313f0a808 100644 --- a/sqlx-macros/src/lib.rs +++ b/sqlx-macros/src/lib.rs @@ -7,11 +7,11 @@ 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(test))] +#[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(test)] +#[cfg(sqlx_macros_namespace)] const CRATE_NAME: &str = env!("SQLX_NAMESPACE"); #[cfg(feature = "macros")] @@ -109,31 +109,3 @@ pub fn test(args: TokenStream, input: TokenStream) -> TokenStream { } } } - -#[cfg(test)] -mod tests { - #[test] - #[cfg(feature = "migrate")] - fn test_macros_namespace_migrate() { - /// 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; - - let _ = external::migrate!("../tests/migrate/migrations_simple"); - } - - #[test] - #[cfg(feature = "derive")] - fn test_macros_namespace_derive() { - /// 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; - - #[derive(Debug, external::Type, external::Encode, external::Decode, external::FromRow)] - struct Test {} - } -} 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, + } +} From 5203bd14d23eaa179aaff15d48304c5f133f2007 Mon Sep 17 00:00:00 2001 From: Bogdan Mircea Date: Tue, 22 Jul 2025 18:09:01 +0300 Subject: [PATCH 5/5] silence proc-macro errors --- sqlx-macros-core/src/query/args.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sqlx-macros-core/src/query/args.rs b/sqlx-macros-core/src/query/args.rs index 4b3af4ed38..3e61bf5d86 100644 --- a/sqlx-macros-core/src/query/args.rs +++ b/sqlx-macros-core/src/query/args.rs @@ -65,7 +65,7 @@ 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 ::#crate_name::ty_match::{WrapSameExt as _, MatchBorrowExt as _};