Skip to main content

xabi_macros/
lib.rs

1use proc_macro::TokenStream;
2use proc_macro2::TokenStream as TokenStream2;
3use syn::{Error, Item};
4
5mod args;
6mod data_macro;
7mod method;
8mod module_macro;
9mod opaque_macro;
10mod trait_macro;
11mod type_shape;
12
13#[cfg(test)]
14mod tests;
15
16#[proc_macro_attribute]
17pub fn xabi(attr: TokenStream, item: TokenStream) -> TokenStream {
18    match expand_xabi(attr.into(), item.into()) {
19        Ok(tokens) => tokens.into(),
20        Err(err) => err.to_compile_error().into(),
21    }
22}
23
24#[proc_macro_attribute]
25pub fn module(attr: TokenStream, item: TokenStream) -> TokenStream {
26    match module_macro::expand_module(attr.into(), item.into()) {
27        Ok(tokens) => tokens.into(),
28        Err(err) => err.to_compile_error().into(),
29    }
30}
31
32#[proc_macro_attribute]
33pub fn data(attr: TokenStream, item: TokenStream) -> TokenStream {
34    match data_macro::expand_data(attr.into(), item.into()) {
35        Ok(tokens) => tokens.into(),
36        Err(err) => err.to_compile_error().into(),
37    }
38}
39
40#[proc_macro_attribute]
41pub fn opaque(attr: TokenStream, item: TokenStream) -> TokenStream {
42    match opaque_macro::expand_opaque(attr.into(), item.into()) {
43        Ok(tokens) => tokens.into(),
44        Err(err) => err.to_compile_error().into(),
45    }
46}
47
48fn expand_xabi(attr: TokenStream2, item: TokenStream2) -> syn::Result<TokenStream2> {
49    let item = syn::parse2::<Item>(item)?;
50    match item {
51        Item::Trait(item_trait) => trait_macro::expand_xabi_trait(attr, item_trait),
52        Item::Impl(item_impl) => Err(Error::new_spanned(
53            item_impl.impl_token,
54            "`#[xabi]` implementation exports must be placed inside a `#[xabi::module]` module",
55        )),
56        other => Err(Error::new_spanned(
57            other,
58            "`#[xabi]` can only be applied to traits or implementation exports",
59        )),
60    }
61}