As asked by @isaactfa,
PS C:\...> rustc --version
rustc 1.62.1 (e092d0b6b 2022-07-16)
// Cargo.toml
[dependencies]
diesel = { version = "1.4.5", features = ["postgres", "sqlite", "chrono"] }
chrono = "0.4"
libsqlite3-sys = { version = "^0", features = ["bundled"] }
Original Post
I've looked at the code more than a dozen times here: What fragment specifiers (metavariable types) should be used in macro-by-example for a module path + type name?, and I fear I'm too dense to grasp it. I tried tinkering with it myself but don't understand what's happening. I looked for examples and tutorials for Rust macros but are either too basic or too advance that half of the words are alien to me.
Like OP on that SO post, I'm using diesel
. Now, how can I use as a macro!()
parameter a module path? A module that is created by diesel::table!()
?
The following code works:
use diesel::table;
table! {
user (id) {
id -> Integer,
uuid -> Text,
username -> Text,
}
}
#[derive(Queryable)]
struct User {
id: i32,
uuid: String,
username: String
}
macro_rules! my_macro {
($table:path, $username:path) => {
impl User {
pub fn search_w_username(
username: String,
conn: &DB,
) -> Result<Option<Self>, diesel::result::Error> {
use crate::diesel::ExpressionMethods;
use crate::diesel::{QueryDsl, RunQueryDsl};
match $table
.filter($username.eq(username))
.load::<User>(conn)
{
...
}
}
}
};
}
my_macro!(user::table, user::columns::username);
But of course, the code above is a code accepted from a defeated man, and it's bugging me for more than a week now.
using the same code above, the following would fail to compile
use diesel::table;
...
macro_rules! my_macro {
($module_path:path) => {
use $module_path::table;
use $module_path::columns::username;
...
}
}
Compiler error thrown:
expected one of `.`, `?`, `{`, or an operator, found `::`
As mentioned by Chayim Friedman who answered the SO post above, the error above is due to an invalid AST (another term I don't understand).
What metavariables and/or how to implement the mentioned "tt_munching", that I'm also having a hard time to understand, should be done so that the macro function signature should just be like the following:
use diesel::table
table! {
user (id) {
id -> Integer,
uuid -> Text,
username -> Text,
}
}
macro_rules! my_macro {
...
}
my_macro!(user);