如下,要实现{}与后面的参数数量编译期检查
tokens!("SELECT {}, COUNT(*) OVER() AS total, ROW_NUMBER OVER () AS rid FROM {} WHERE {}", select, table, where_)
目前比较笨的方法借助format!宏,这样写到差不多16
#[macro_export]
macro_rules! tokens {
($fmt:expr, $a1:expr) => {{
let text = format!($fmt, "{}");
let tokens: Vec<$crate::Token> = vec![$a1.into()];
$crate::tokens_compile!(text, tokens)
}};
($fmt:expr, $a1:expr, $a2:expr) => {{
let text = format!($fmt, "{}", "{}");
let tokens: Vec<$crate::Token> = vec![$a1.into(), $a2.into()];
$crate::tokens_compile!(text, tokens)
}};
($fmt:expr, $a1:expr, $a2:expr, $a3:expr) => {{
let text = format!($fmt, "{}", "{}", "{}");
let tokens: Vec<$crate::Token> = vec![$a1.into(), $a2.into(), $a3.into()];
$crate::tokens_compile!(text, tokens)
}};
($fmt:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr) => {{
let text = format!($fmt, "{}", "{}", "{}", "{}");
let tokens: Vec<$crate::Token> = vec![$a1.into(), $a2.into(), $a3.into(), $a4.into()];
$crate::tokens_compile!(text, tokens)
}};
($fmt:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr) => {{
let text = format!($fmt, "{}", "{}", "{}", "{}", "{}");
let tokens: Vec<$crate::Token> =
vec![$a1.into(), $a2.into(), $a3.into(), $a4.into(), $a5.into()];
$crate::tokens_compile!(text, tokens)
}};
($fmt:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr, $a6:expr) => {{
let text = format!($fmt, "{}", "{}", "{}", "{}", "{}", "{}");
let tokens: Vec<$crate::Token> =
vec![$a1.into(), $a2.into(), $a3.into(), $a4.into(), $a5.into(), $a6.into()];
$crate::tokens_compile!(text, tokens)
}};
// todo
}
1
共 6 条评论, 1 页
评论区
写评论你这个可以看看宏小册,里面有个叫什么撕咬机的写法。可以实现你这个思路。
我简单写了例子,不怎么常写宏,仅供参考。
我主要就希望能够检查{}和后面参数数量是否对等
--
👇
Bai-Jinlin: sqlx已经搞了编译期检测sql语句了,用的过程宏,并且编译期检测sql会搞得编译速度很慢。
我还是先简单的从0写道16匹配吧,后面再看看过程宏
--
👇
LazyBoy: macro_rules应该是没法直接满足你的需求,应该它是定义声明宏的,即只能通过一些简单的匹配声明来实现宏。对于你需求的复杂解析需求,需要使用使用过程宏里的类函数宏,即类似函数在编译时运行,可以实现非常复杂的解析需求,如同常规程序编写函数一样。
此外,对于你提供的基于format宏的写法,也有一种优化手段(简写,但是需要特性支持):
macro_rules应该是没法直接满足你的需求,应该它是定义声明宏的,即只能通过一些简单的匹配声明来实现宏。对于你需求的复杂解析需求,需要使用使用过程宏里的类函数宏,即类似函数在编译时运行,可以实现非常复杂的解析需求,如同常规程序编写函数一样。
此外,对于你提供的基于format宏的写法,也有一种优化手段(简写,但是需要特性支持):
不太熟悉数据库,但现在的参数化查询有什么问题吗对比贴主的做法
sqlx已经搞了编译期检测sql语句了,用的过程宏,并且编译期检测sql会搞得编译速度很慢。