// The #[sorted] macro is only defined to work on enum types, so this is a test
// to ensure that when it's attached to a struct (or anything else) it produces
// some reasonable error. Your macro will need to look into the syn::Item that
// it parsed to ensure that it represents an enum, returning an error for any
// other type of Item such as a struct.
//
// This is an exercise in exploring how to return errors from procedural macros.
// The goal is to produce an understandable error message which is tailored to
// this specific macro (saying that #[sorted] cannot be applied to things other
// than enum). For this you'll want to look at the syn::Error type, how to
// construct it, and how to return it.
//
// Notice that the return value of an attribute macro is simply a TokenStream,
// not a Result with an error. The syn::Error type provides a method to render
// your error as a TokenStream containing an invocation of the compile_error
// macro.
//
// A final tweak you may want to make is to have the `sorted` function delegate
// to a private helper function which works with Result, so most of the macro
// can be written with Result-returning functions while the top-level function
// handles the conversion down to TokenStream.
//
//
// Resources
//
// - The syn::Error type:
// https://docs.rs/syn/1.0/syn/struct.Error.html
use sorted::sorted;
#[sorted]
pub struct Error {
kind: ErrorKind,
message: String,
}
enum ErrorKind {
Io,
Syntax,
Eof,
}
fn main() {}
這道題主要是報錯
error: expected enum or match expression
--> tests/02-not-enum.rs:31:1
|
31 | #[sorted]
| ^^^^^^^^^
|
= note: this error originates in the attribute macro `sorted` (in Nightly builds, run with -Z macro-backtrace for more info)
標識的是隻能夠標記在enum
上。
pub(crate) fn solution(item: &syn::Item) -> syn::Result<proc_macro2::TokenStream> {
match item {
syn::Item::Enum(node) => crate::solution3::solution(node),
_ => syn::Result::Err(syn::Error::new(
proc_macro2::Span::call_site(),
"expected enum or match expression",
)),
}
}
模式匹配即可,順便引出第三個坑。
proc_macro2:: Span::call_site()
真香
#[proc_macro_attribute]
pub fn sorted(
_args: proc_macro::TokenStream,
input: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
let item = syn::parse_macro_input!(input as syn::Item);
match solution1::solution(&item) {
syn::Result::Ok(stream) => stream,
syn::Result::Err(e) => {
let mut res = e.into_compile_error();
res.extend(crate::common::to_token_stream(item));
res
}
}
.into()
}
整體結構不變。
本作品採用《CC 協議》,轉載必須註明作者和本文連結