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 let lit = input.parse::<LitInt>()?;
14
15 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 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}