regiface_macros/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse::Parse, parse::ParseStream, parse_macro_input, DeriveInput, Ident, LitInt};
4
5struct RegisterAttr {
6    value: LitInt,
7    ty: Ident,
8}
9
10impl Parse for RegisterAttr {
11    fn parse(input: ParseStream) -> syn::Result<Self> {
12        // Parse the entire input as a single LitInt first
13        let lit = input.parse::<LitInt>()?;
14
15        // Extract the type suffix from the literal
16        let suffix = lit.suffix();
17        if suffix.is_empty() {
18            return Err(syn::Error::new(
19                lit.span(),
20                "Expected type suffix (e.g., u8, u16)",
21            ));
22        }
23
24        // Create an Ident from the suffix
25        let ty = Ident::new(suffix, lit.span());
26
27        Ok(RegisterAttr { value: lit, ty })
28    }
29}
30
31#[proc_macro_attribute]
32pub fn register(attr: TokenStream, item: TokenStream) -> TokenStream {
33    let attr = parse_macro_input!(attr as RegisterAttr);
34    let input = parse_macro_input!(item as DeriveInput);
35
36    let name = &input.ident;
37    let value = &attr.value;
38    let ty = &attr.ty;
39    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
40
41    let expanded = quote! {
42        #input
43
44        impl #impl_generics regiface::Register for #name #ty_generics #where_clause {
45            type IdType = #ty;
46
47            fn id() -> Self::IdType {
48                #value
49            }
50        }
51    };
52
53    TokenStream::from(expanded)
54}
55
56#[proc_macro_derive(ReadableRegister)]
57pub fn derive_readable_register(input: TokenStream) -> TokenStream {
58    let input = parse_macro_input!(input as DeriveInput);
59    let name = &input.ident;
60    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
61
62    let expanded = quote! {
63        impl #impl_generics regiface::ReadableRegister for #name #ty_generics #where_clause {}
64    };
65
66    TokenStream::from(expanded)
67}
68
69#[proc_macro_derive(WritableRegister)]
70pub fn derive_writable_register(input: TokenStream) -> TokenStream {
71    let input = parse_macro_input!(input as DeriveInput);
72    let name = &input.ident;
73    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
74
75    let expanded = quote! {
76        impl #impl_generics regiface::WritableRegister for #name #ty_generics #where_clause {}
77    };
78
79    TokenStream::from(expanded)
80}