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}