我正在编写一个程序宏,它工作正常,但我无法以符合人体工程学的方式报告错误.使用panic!"工作"但不优雅,并且不会很好地向用户显示错误消息.
我知道我可以在解析a时报告错误TokenStream,但是在解析之后我需要在遍历AST时产生错误.
宏调用如下所示:
attr_test! {
#[bool]
FOO
}
Run Code Online (Sandbox Code Playgroud)
并应输出:
const FOO: bool = false;
Run Code Online (Sandbox Code Playgroud)
这是宏代码:
extern crate proc_macro;
use quote::quote;
use syn::parse::{Parse, ParseStream, Result};
use syn::{Attribute, parse_macro_input, Ident, Meta};
struct AttrTest {
attributes: Vec<Attribute>,
name: Ident,
}
impl Parse for AttrTest {
fn parse(input: ParseStream) -> Result<Self> {
Ok(AttrTest {
attributes: input.call(Attribute::parse_outer)?,
name: input.parse()?,
})
}
}
#[proc_macro]
pub fn attr_test(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
let test: AttrTest = parse_macro_input!(tokens);
let name = test.name;
let first_att …Run Code Online (Sandbox Code Playgroud) 我已经看到了@宏中使用的符号,但我在Rust Book或任何官方文档或博客文章中都找不到它.例如,在此Stack Overflow答案中,它的使用方式如下:
macro_rules! instructions {
(enum $ename:ident {
$($vname:ident ( $($vty: ty),* )),*
}) => {
enum $ename {
$($vname ( $($vty),* )),*
}
impl $ename {
fn len(&self) -> usize {
match self {
$($ename::$vname(..) => instructions!(@count ($($vty),*))),*
}
}
}
};
(@count ()) => (0);
(@count ($a:ty)) => (1);
(@count ($a:ty, $b:ty)) => (2);
(@count ($a:ty, $b:ty, $c:ty)) => (3);
}
instructions! {
enum Instruction {
None(),
One(u8),
Two(u8, u8),
Three(u8, u8, u8) …Run Code Online (Sandbox Code Playgroud)