Is there a way to evaluate a declarative macro early?

⚓ Rust    📅 2025-11-18    👤 surdeus    👁️ 2      

surdeus

Hi, I'm trying to write a wrapper macro for sqlx to give me some more compile-time guarantees for a use-case that is not supported by mariadb (binding a list to ?). For that I want to first concat! something to the query, before passing the result to sqlx' query_as! macro:

macro_rules! query_in_list {
    ($ty:ty, $query:literal for $name:ident in $list:ident) => {
        query_in_list!($ty, $query for $name in $list { $name })
    };
    ($ty:ty, $query:literal for $name:ident in $list:ident { $block:expr }) => {{
        let _ = sqlx::query_as!($ty, concat!($query, "( ? );"));
        let _ = sqlx::query_as!($ty, concat!($query, "( ?, ? );"));

        let mut builder = sqlx::QueryBuilder::new(concat!($query, " ( "));
        let mut separated = builder.separated(", ");
        for $name in $list {
            separated.push_bind($block);
        }
        separated.push_unseparated(" );");

        builder
    }};
}

let builder = query_in_list! {
    OrgPermissionsQueryResult,
    r#"SELECT organization_id AS org_id, permissions
       FROM roles
       JOIN roles_permissions_organization USING (role_id)
       WHERE idp_group IN "#
    for group in groups
};

This however does not work, as it tries to pass the whole concat!(...) into the macro, instead of just the result? Is there any way to evaluate it early? e.g. concat!! or passing it to an "early evaluate" macro or something similar?

1 post - 1 participant

Read full topic

🏷️ Rust_feed