Skip to content

Commit

Permalink
fix: solved a bug in the CanyonMapper macro that was causing issues t…
Browse files Browse the repository at this point in the history
…o the conditionally compiled code
  • Loading branch information
TheRustifyer committed Dec 19, 2024
1 parent e229264 commit 0840a57
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 20 deletions.
3 changes: 1 addition & 2 deletions canyon_macros/src/canyon_macro.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//! Provides helpers to build the `#[canyon_macros::canyon]` procedural like attribute macro
#![cfg(feature = "migrations")]

use canyon_connection::CANYON_TOKIO_RUNTIME;
use canyon_migrations::migrations::handler::Migrations;
use canyon_migrations::{CM_QUERIES_TO_EXECUTE, QUERIES_TO_EXECUTE};
use proc_macro2::TokenStream;
use quote::quote;

#[cfg(feature = "migrations")]
pub fn main_with_queries() -> TokenStream {
CANYON_TOKIO_RUNTIME.block_on(async {
canyon_connection::init_connections_cache().await;
Expand All @@ -25,7 +25,6 @@ pub fn main_with_queries() -> TokenStream {

/// Creates a TokenScream that is used to load the data generated at compile-time
/// by the `CanyonManaged` macros again on the queries register
#[cfg(feature = "migrations")]
fn wire_queries_to_execute(canyon_manager_tokens: &mut Vec<TokenStream>) {
let cm_data = CM_QUERIES_TO_EXECUTE.lock().unwrap();
let data = QUERIES_TO_EXECUTE.lock().unwrap();
Expand Down
60 changes: 42 additions & 18 deletions canyon_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod utils;
use canyon_entity_macro::parse_canyon_entity_proc_macro_attr;
use proc_macro::TokenStream as CompilerTokenStream;
use proc_macro2::{Ident, TokenStream};
use quote::{quote, ToTokens};
use quote::quote;
use syn::{DeriveInput, Fields, Type, Visibility};

use query_operations::{
Expand Down Expand Up @@ -442,6 +442,11 @@ pub fn implement_row_mapper_for_type(input: proc_macro::TokenStream) -> proc_mac
}
});


// TODO: refactor the code below after the current bugfixes, to conditinally generate
// the required methods and populate the CanyonMapper trait dependencing on the cfg flags
// enabled with a more elegant solution (a fn for feature, for ex)
#[cfg(feature = "postgres")]
// Here it's where the incoming values of the DatabaseResult are wired into a new
// instance, mapping the fields of the type against the columns
let init_field_values = fields.iter().map(|(_vis, ident, _ty)| {
Expand All @@ -452,6 +457,8 @@ pub fn implement_row_mapper_for_type(input: proc_macro::TokenStream) -> proc_mac
}
});


#[cfg(feature = "mssql")]
let init_field_values_sqlserver = fields.iter().map(|(_vis, ident, ty)| {
let ident_name = ident.to_string();

Expand Down Expand Up @@ -530,6 +537,7 @@ pub fn implement_row_mapper_for_type(input: proc_macro::TokenStream) -> proc_mac
}
});

#[cfg(feature = "mysql")]
let init_field_values_mysql = fields.iter().map(|(_vis, ident, _ty)| {
let ident_name = ident.to_string();
quote! {
Expand All @@ -541,27 +549,40 @@ pub fn implement_row_mapper_for_type(input: proc_macro::TokenStream) -> proc_mac
// The type of the Struct
let ty = ast.ident;

let tokens = quote! {
impl canyon_sql::crud::RowMapper<Self> for #ty {
#[cfg(feature="postgres")]
fn deserialize_postgresql(row: &canyon_sql::db_clients::tokio_postgres::Row) -> #ty {
Self {
#(#init_field_values),*
}
let mut impl_methods = quote! {}; // Collect methods conditionally

#[cfg(feature = "postgres")]
impl_methods.extend(quote! {
fn deserialize_postgresql(row: &canyon_sql::db_clients::tokio_postgres::Row) -> #ty {
Self {
#(#init_field_values),*
}
#[cfg(feature="mssql")]
fn deserialize_sqlserver(row: &canyon_sql::db_clients::tiberius::Row) -> #ty {
Self {
#(#init_field_values_sqlserver),*
}
}
});

#[cfg(feature = "mssql")]
impl_methods.extend(quote! {
fn deserialize_sqlserver(row: &canyon_sql::db_clients::tiberius::Row) -> #ty {
Self {
#(#init_field_values_sqlserver),*
}
#[cfg(feature="mysql")]
fn deserialize_mysql(row: &canyon_sql::db_clients::mysql_async::Row) -> #ty {
Self {
#(#init_field_values_mysql),*
}
}
});

#[cfg(feature = "mysql")]
impl_methods.extend(quote! {
fn deserialize_mysql(row: &canyon_sql::db_clients::mysql_async::Row) -> #ty {
Self {
#(#init_field_values_mysql),*
}
}
});

// Wrap everything in the shared `impl` block
let tokens = quote! {
impl canyon_sql::crud::RowMapper<Self> for #ty {
#impl_methods
}
};

tokens.into()
Expand All @@ -588,6 +609,9 @@ fn fields_with_types(fields: &Fields) -> Vec<(Visibility, Ident, Type)> {
.collect::<Vec<_>>()
}

#[cfg(feature = "mssql")]
use quote::ToTokens;
#[cfg(feature = "mssql")]
fn get_field_type_as_string(typ: &Type) -> String {
match typ {
Type::Array(type_) => type_.to_token_stream().to_string(),
Expand Down

0 comments on commit 0840a57

Please sign in to comment.