在字符串中提取宏参数

extract macro argument inside string

我有以下宏:-

macro_rules! update_user {
    ($tx:ident, $id:expr, $key:expr, $val:expr) => {
        sqlx::query!(
            "UPDATE users SET
            $key = ?
            WHERE id = $id
            "
            , $val
        ).execute(&mut $tx).await?;

    };
}

如何让这个宏在字符串中使用 $id 和 $key 的值?我不能使用 format! 因为 query! 只需要字符串文字

编辑;连连!宏不工作


macro_rules! update  {
    ($tx:ident, $col:tt, $val:expr, $id:expr) => {
        if let Some(some) = $val {
            sqlx::query!(
                concat!(
                "UPDATE users SET",
                $col ," = ?  ",
                "where id = ? "
                ),
                some, $id
            ).execute(&mut $tx).await?;
        }
    };
}

pub(crate) async fn update_user<'a> (
    db : &MySqlPool,
    user : User<'a>,
) -> RouteResult<()> {

    let mut tx = db.begin().await?;

    update!(tx, "uname", user.uname, user.id);

    if let Some(uname) = user.uname {
        sqlx::query!(
            "UPDATE users SET
            uname = ? 
            where id = ? 
            ",
            uname, user.id
        ).execute(&mut tx).await?;
    }

    tx.commit().await?;

    Ok(())
}

这会产生 expected string literal 错误。

为此您可能需要 concat!()。它将连接文字以产生 &'static str:

macro_rules! update_user {
    ($tx:ident, $id:expr, $key:expr, $val:expr) => {
        sqlx::query!(
            concat!("UPDATE users SET $key = ", $key, " WHERE id = ", $id),
            $val
        ).execute(&mut $tx).await?;

    };
}

类似的例子:Playground

在 sqlx 的 discord 论坛上得到了答案。我不得不使用 + 而不是 concat!。我接受 Mihir 的回答,因为它回答了标题,但我不得不使用以下

macro_rules! update {
    ($tx:ident, $table:tt, $col:tt, $val:expr, $id:expr) => {
        if let Some(some) = $val {
            sqlx::query!(
                "UPDATE "
                    + $table
                    + " SET "
                    + $col
                    + " = ?  
                where id = ? ",
                some,
                $id
            )
            .execute(&mut $tx)
            .await?;
        }
    };
}
...
//use it like this
update!(tx, "users", "uname", user.uname, user.id);