我正试图为宏创建的结构成员函数编写一个文档测试。显然,只能在独立的文档属性中使用捕获。但是,这会强制在文档测试中使用换行符,以便捕获填充渲染结果中的整行。这是一种防止换行的方法,还是在不使用程序宏的情况下直接使用捕获?
#[macro_export]
macro_rules! gen_functions {
($name:tt) => {
/// # Usage
///
/// ```
/// let h =
#[doc = $name]
/// {};
/// h.test_a();
/// ```
pub fn test_a(&self) {
println!("test a")
}
};
}
pub struct CustomStruct {}
impl CustomStruct {
gen_functions!("CustomStruct");
}
fn main() {
let h = CustomStruct {};
h.test_a();
}
以及由此产生的文档测试。它确实可以编译,但很难阅读(与主函数中的版本相比(:
let h =
CustomStruct
{};
h.test_a();
有人向我展示了一个关于这个内部线程的不错的解决方案,它使用了一个宏。我调整了宏,使其更易于使用。
用法:
macro_rules! gen_functions {
($name:tt) => {
doc! {
/// # Usage
///
/// ```
[concat!(" let h = ", $name, " {};")]
/// h.test_a();
/// ```
@ pub fn test_a(&self) {
println!("test a")
}
}
};
}
这就是宏:
macro_rules! doc {
{
$(#[$m:meta])*
$(
[$doc:expr]
$(#[$n:meta])*
)*
@ $thing:item
} => {
$(#[$m])*
$(
#[doc = $doc]
$(#[$n])*
)*
$thing
}
}
宏将[
方括号]
中的字符串转换为#[doc = _]
属性。它的特殊之处在于它可以包含concat!还有黏糊糊的!宏调用。它们也可以组合,例如
doc! {
/// # Usage
///
/// ```
[concat!(" let ", stringify!(h), " = ", stringify!(CustomStruct), " {};")]
/// h.test_a();
/// ```
@ pub fn test_a(&self) {
println!("test a")
}
}