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::ToTokens;
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 match machine_check_machine::process_module(module) {
23 Ok(ok) => ok.into_token_stream().into(),
24 Err(err) => {
25 let (first_error, other_errors) = err.into_errors().split_off_first();
26 let mut current_error = first_error.into_syn_error();
27 for error in other_errors {
28 current_error.combine(error.into_syn_error());
29 }
30 current_error.to_compile_error().into()
31 }
32 }
33}
34
35#[proc_macro]
36pub fn bitmask_switch(stream: TokenStream) -> TokenStream {
37 let switch = parse_macro_input!(stream as BitmaskSwitch);
38 match machine_check_bitmask_switch::generate(switch) {
39 Ok(ok) => TokenStream::from(ok),
40 Err(error) => match error {
41 machine_check_bitmask_switch::Error::Parse(error) => error.into_compile_error().into(),
42 machine_check_bitmask_switch::Error::Process(msg, span) => {
43 syn::Error::new(span, msg).into_compile_error().into()
44 }
45 },
46 }
47}