1use crate::attr::{self, Attrs};
2use proc_macro2::Span;
3use syn::{
4 Data, DataEnum, DataStruct, DeriveInput, Error, Fields, Generics, Ident, Index, Member, Result,
5 Type,
6};
7
8pub enum Input<'a> {
9 Struct(Struct<'a>),
10 Enum(Enum<'a>),
11}
12
13pub struct Struct<'a> {
14 pub original: &'a DeriveInput,
15 pub attrs: Attrs<'a>,
16 pub ident: Ident,
17 pub generics: &'a Generics,
18 pub fields: Vec<Field<'a>>,
19}
20
21pub struct Enum<'a> {
22 pub original: &'a DeriveInput,
23 pub attrs: Attrs<'a>,
24 pub ident: Ident,
25 pub generics: &'a Generics,
26 pub variants: Vec<Variant<'a>>,
27}
28
29pub struct Variant<'a> {
30 pub original: &'a syn::Variant,
31 pub attrs: Attrs<'a>,
32 pub ident: Ident,
33 pub fields: Vec<Field<'a>>,
34}
35
36pub struct Field<'a> {
37 pub original: &'a syn::Field,
38 pub attrs: Attrs<'a>,
39 pub member: Member,
40 pub ty: &'a Type,
41}
42
43impl<'a> Input<'a> {
44 pub fn from_syn(node: &'a DeriveInput) -> Result<Self> {
45 match &node.data {
46 Data::Struct(data) => Struct::from_syn(node, data).map(Input::Struct),
47 Data::Enum(data) => Enum::from_syn(node, data).map(Input::Enum),
48 Data::Union(_) => Err(Error::new_spanned(
49 node,
50 "union as errors are not supported",
51 )),
52 }
53 }
54}
55
56impl<'a> Struct<'a> {
57 fn from_syn(node: &'a DeriveInput, data: &'a DataStruct) -> Result<Self> {
58 let attrs = attr::get(&node.attrs)?;
59 let span = Span::call_site();
60 let fields = Field::multiple_from_syn(&data.fields, span)?;
61 Ok(Struct {
62 original: node,
63 attrs,
64 ident: node.ident.clone(),
65 generics: &node.generics,
66 fields,
67 })
68 }
69}
70
71impl<'a> Enum<'a> {
72 fn from_syn(node: &'a DeriveInput, data: &'a DataEnum) -> Result<Self> {
73 let attrs = attr::get(&node.attrs)?;
74 let span = Span::call_site();
75 let variants = data
76 .variants
77 .iter()
78 .map(|node| {
79 let variant = Variant::from_syn(node, span)?;
80 Ok(variant)
81 })
82 .collect::<Result<_>>()?;
83 Ok(Enum {
84 original: node,
85 attrs,
86 ident: node.ident.clone(),
87 generics: &node.generics,
88 variants,
89 })
90 }
91}
92
93impl<'a> Variant<'a> {
94 fn from_syn(node: &'a syn::Variant, span: Span) -> Result<Self> {
95 let attrs = attr::get(&node.attrs)?;
96 Ok(Variant {
97 original: node,
98 attrs,
99 ident: node.ident.clone(),
100 fields: Field::multiple_from_syn(&node.fields, span)?,
101 })
102 }
103}
104
105impl<'a> Field<'a> {
106 fn multiple_from_syn(fields: &'a Fields, span: Span) -> Result<Vec<Self>> {
107 fields
108 .iter()
109 .enumerate()
110 .map(|(i, field)| Field::from_syn(i, field, span))
111 .collect()
112 }
113
114 fn from_syn(i: usize, node: &'a syn::Field, span: Span) -> Result<Self> {
115 Ok(Field {
116 original: node,
117 attrs: attr::get(&node.attrs)?,
118 member: node.ident.clone().map(Member::Named).unwrap_or_else(|| {
119 Member::Unnamed(Index {
120 index: i as u32,
121 span,
122 })
123 }),
124 ty: &node.ty,
125 })
126 }
127}