armour_derive/
lib.rs

1#[macro_use]
2extern crate darling;
3extern crate proc_macro2;
4extern crate quote;
5extern crate syn;
6
7use darling::util::Flag;
8use syn::{Data, DeriveInput, Expr, ExprPath, LitStr, parse_macro_input};
9
10mod enum_parse;
11mod struct_parse;
12
13/// - `#[get_type(idx = 1)]` in fields
14/// - `#[get_type(flatten)]` for unnamed structs
15/// - `#[get_type(with_type(Type))]` for named struct fields
16/// - `#[get_type(unimplemented)]` for named struct fields
17/// - `#[get_type(custom("name", &[Typ::Bool, Typ::Str]))]` for named struct fields
18#[proc_macro_derive(GetType, attributes(idx, get_type))]
19pub fn derive_get_type(stream: proc_macro::TokenStream) -> proc_macro::TokenStream {
20    let ast = parse_macro_input!(stream as DeriveInput);
21    let name = ast.ident;
22    let data = &ast.data;
23
24    match data {
25        Data::Struct(data_struct) => struct_parse::parse(data_struct, name).into(),
26        Data::Enum(data_enum) => enum_parse::parse(data_enum, name),
27        Data::Union(_) => {
28            panic!(
29                "unions not supported, but Rust enums is implemented GetType trait (use Enums instead)"
30            )
31        }
32    }
33}
34
35#[derive(FromMeta, Debug)]
36struct CustomField {
37    name: LitStr,
38    types: Expr,
39}
40
41#[derive(Default, FromField, Debug)]
42#[darling(attributes(get_type))]
43pub(crate) struct FieldAttr {
44    pub(crate) idx: Option<u32>,
45    pub(crate) with_type: Option<ExprPath>,
46    pub(crate) unimplemented: Flag,
47    pub(crate) custom: Option<CustomField>,
48    pub(crate) flatten: Flag,
49}