machine_check_macros/
lib.rs

1#![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}