syn_error_experiment/
ast.rs

1use proc_macro2::Ident;
2
3use parse::{Parse, ParseStream, Result};
4use token;
5
6/// Things that can appear directly inside of a module or scope.
7#[derive(Debug)]
8pub enum Item {
9    Struct(ItemStruct),
10    Enum(ItemEnum),
11}
12
13/// A struct definition: `struct S { a: A, b: B }`.
14#[derive(Debug)]
15pub struct ItemStruct {
16    pub struct_token: Token![struct],
17    pub ident: Ident,
18    pub brace_token: token::Brace,
19    pub fields: Vec<Field>,
20}
21
22/// An enum definition: `enum E { A, B, C }`.
23#[derive(Debug)]
24pub struct ItemEnum {
25    pub enum_token: Token![enum],
26    pub ident: Ident,
27    pub brace_token: token::Brace,
28    pub variants: Vec<Variant>,
29}
30
31/// A named field of a braced struct.
32#[derive(Debug)]
33pub struct Field {
34    pub name: Ident,
35    pub colon_token: Token![:],
36    pub ty: Ident,
37    pub comma_token: Token![,],
38}
39
40/// An enum variant.
41#[derive(Debug)]
42pub struct Variant {
43    pub name: Ident,
44    pub comma_token: token::Comma,
45}
46
47impl Parse for Item {
48    fn parse(input: ParseStream) -> Result<Self> {
49        let lookahead = input.lookahead1();
50        if lookahead.peek(Token![struct]) {
51            input.parse().map(Item::Struct)
52        } else if lookahead.peek(Token![enum]) {
53            input.parse().map(Item::Enum)
54        } else {
55            Err(lookahead.error())
56        }
57    }
58}
59
60impl Parse for ItemStruct {
61    fn parse(input: ParseStream) -> Result<Self> {
62        let content;
63        Ok(ItemStruct {
64            struct_token: input.parse()?,
65            ident: input.parse()?,
66            brace_token: braced!(content in input),
67            fields: content.parse()?,
68        })
69    }
70}
71
72impl Parse for ItemEnum {
73    fn parse(input: ParseStream) -> Result<Self> {
74        let content;
75        Ok(ItemEnum {
76            enum_token: input.parse()?,
77            ident: input.parse()?,
78            brace_token: braced!(content in input),
79            variants: content.parse()?,
80        })
81    }
82}
83
84impl Parse for Field {
85    fn parse(input: ParseStream) -> Result<Self> {
86        Ok(Field {
87            name: input.parse()?,
88            colon_token: input.parse()?,
89            ty: input.parse()?,
90            comma_token: input.parse()?,
91        })
92    }
93}
94
95impl Parse for Variant {
96    fn parse(input: ParseStream) -> Result<Self> {
97        Ok(Variant {
98            name: input.parse()?,
99            comma_token: input.parse()?,
100        })
101    }
102}