tosserror_derive/
ast.rs

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}