machine_check_macros/
lib.rs1#![doc = include_str!("../README.md")]
2
3extern crate proc_macro;
4
5use machine_check_bitmask_switch::BitmaskSwitch;
6use proc_macro::TokenStream;
7use quote::quote;
8use syn::{parse_macro_input, spanned::Spanned, Item};
9
10#[proc_macro_attribute]
11pub fn machine_description(_attr: TokenStream, item: TokenStream) -> TokenStream {
12 let item = parse_macro_input!(item as Item);
13 let Item::Mod(module) = item else {
14 return syn::Error::new(
15 item.span(),
16 String::from("machine_description macro must be used on a module"),
17 )
18 .to_compile_error()
19 .into();
20 };
21
22 let module = match machine_check_machine::process_module(module) {
23 Ok(ok) => ok,
24 Err(err) => {
25 return syn::Error::new(err.span, err.ty.to_string())
26 .to_compile_error()
27 .into();
28 }
29 };
30
31 let expanded = quote! {
32 #module
33 };
34 TokenStream::from(expanded)
35}
36
37#[proc_macro]
38pub fn bitmask_switch(stream: TokenStream) -> TokenStream {
39 let switch = parse_macro_input!(stream as BitmaskSwitch);
40 match machine_check_bitmask_switch::generate(switch) {
41 Ok(ok) => TokenStream::from(ok),
42 Err(error) => match error {
43 machine_check_bitmask_switch::Error::Parse(error) => error.into_compile_error().into(),
44 machine_check_bitmask_switch::Error::Process(msg, span) => {
45 syn::Error::new(span, msg).into_compile_error().into()
46 }
47 },
48 }
49}