Skip to main content

aranya_capi_codegen/syntax/
file.rs

1use proc_macro2::TokenStream;
2use quote::ToTokens;
3use syn::{
4    ItemConst, ItemEnum, ItemFn, ItemImpl, ItemStruct, ItemType, ItemUnion, ItemUse, Result,
5    parse::{Parse, ParseStream},
6};
7
8/// An item that can appear inside a C API.
9#[derive(Clone, Debug, Eq, PartialEq)]
10pub enum Item {
11    /// `const FOO: u16 = ...`;
12    Const(ItemConst),
13    /// `enum Foo { ...  }`.
14    Enum(ItemEnum),
15    /// `fn foo() { ... }`.
16    Fn(ItemFn),
17    /// `impl Bar for Foo { ... }`.
18    Impl(ItemImpl),
19    /// Something else.
20    Other(syn::Item),
21    /// `struct Foo { ... }`.
22    Struct(ItemStruct),
23    /// `type Foo = ...`.
24    Type(ItemType),
25    /// `union Foo { ... }`.
26    Union(ItemUnion),
27    /// `use crate::Foo;`.
28    Use(ItemUse),
29}
30
31macro_rules! from_impl {
32    ($($from:ty => $variant:ident),+ $(,)?) => {
33        $(
34            impl From<$from> for Item {
35                fn from(v: $from) -> Self {
36                    Self::$variant(v)
37                }
38            }
39        )+
40    };
41}
42from_impl! {
43    ItemConst => Const,
44    ItemEnum => Enum,
45    ItemImpl => Impl,
46    ItemStruct => Struct,
47    ItemType => Type,
48    ItemUnion => Union,
49    ItemUse => Use,
50}
51
52impl From<syn::Item> for Item {
53    fn from(item: syn::Item) -> Self {
54        match item {
55            syn::Item::Const(v) => Self::Const(v),
56            syn::Item::Enum(v) => Self::Enum(v),
57            syn::Item::Fn(v) => Self::Fn(v),
58            syn::Item::Impl(v) => Self::Impl(v),
59            syn::Item::Struct(v) => Self::Struct(v),
60            syn::Item::Type(v) => Self::Type(v),
61            syn::Item::Union(v) => Self::Union(v),
62            syn::Item::Use(v) => Self::Use(v),
63            other => Self::Other(other),
64        }
65    }
66}
67
68impl Parse for Item {
69    fn parse(input: ParseStream<'_>) -> Result<Self> {
70        let item = input.parse::<syn::Item>()?;
71        Ok(item.into())
72    }
73}
74
75impl ToTokens for Item {
76    fn to_tokens(&self, tokens: &mut TokenStream) {
77        match self {
78            Self::Const(v) => v.to_tokens(tokens),
79            Self::Enum(v) => v.to_tokens(tokens),
80            Self::Fn(v) => v.to_tokens(tokens),
81            Self::Impl(v) => v.to_tokens(tokens),
82            Self::Struct(v) => v.to_tokens(tokens),
83            Self::Type(v) => v.to_tokens(tokens),
84            Self::Union(v) => v.to_tokens(tokens),
85            Self::Use(v) => v.to_tokens(tokens),
86            Self::Other(v) => v.to_tokens(tokens),
87        }
88    }
89}