blob: 544b55f3eb9dcadc488fc468a9ca8998ced0d57f [file] [log] [blame]
David Tolnayb79ee962016-09-04 09:39:20 -07001use super::*;
2
3use attr::attribute;
4use common::{word, visibility};
5use generics::generics;
6use ty::ty;
David Tolnay65e7f302016-09-04 10:19:25 -07007use nom::multispace;
David Tolnayb79ee962016-09-04 09:39:20 -07008
9#[derive(Debug, Clone, Eq, PartialEq)]
10pub struct Item {
11 pub ident: Ident,
12 pub vis: Visibility,
13 pub attrs: Vec<Attribute>,
14 pub generics: Generics,
15 pub body: Body,
16}
17
18#[derive(Debug, Clone, Eq, PartialEq)]
19pub enum Body {
20 Enum(Vec<Variant>),
21 Struct(Style, Vec<Field>),
22}
23
24#[derive(Debug, Clone, Eq, PartialEq)]
25pub struct Variant {
26 pub ident: Ident,
27 pub attrs: Vec<Attribute>,
28 pub style: Style,
29 pub fields: Vec<Field>,
30}
31
32#[derive(Debug, Clone, Eq, PartialEq)]
33pub enum Style {
34 Struct,
35 Tuple,
36 Unit,
37}
38
39#[derive(Debug, Clone, Eq, PartialEq)]
40pub struct Field {
41 pub ident: Option<Ident>,
42 pub vis: Visibility,
43 pub attrs: Vec<Attribute>,
44 pub ty: Ty,
45}
46
David Tolnay6b7aaf02016-09-04 10:39:25 -070047named!(pub item<&str, Item>, do_parse!(
48 attrs: many0!(attribute) >>
49 vis: visibility >>
50 which: alt!(tag_s!("struct") | tag_s!("enum")) >>
51 multispace >>
52 ident: word >>
53 generics: generics >>
David Tolnayb79ee962016-09-04 09:39:20 -070054 item: switch!(value!(which),
55 "struct" => map!(struct_body, move |(style, fields)| Item {
56 ident: ident,
57 vis: vis,
58 attrs: attrs,
59 generics: generics,
60 body: Body::Struct(style, fields),
61 })
62 |
63 "enum" => map!(enum_body, move |body| Item {
64 ident: ident,
65 vis: vis,
66 attrs: attrs,
67 generics: generics,
68 body: body,
69 })
David Tolnay6b7aaf02016-09-04 10:39:25 -070070 ) >>
71 opt!(multispace) >>
72 (item)
David Tolnayb79ee962016-09-04 09:39:20 -070073));
74
75named!(struct_body<&str, (Style, Vec<Field>)>, alt!(
76 struct_like_body => { |fields| (Style::Struct, fields) }
77 |
78 terminated!(tuple_like_body, punct!(";")) => { |fields| (Style::Tuple, fields) }
79 |
80 punct!(";") => { |_| (Style::Unit, Vec::new()) }
81));
82
David Tolnay6b7aaf02016-09-04 10:39:25 -070083named!(enum_body<&str, Body>, do_parse!(
84 punct!("{") >>
85 variants: separated_list!(punct!(","), variant) >>
86 opt!(punct!(",")) >>
87 punct!("}") >>
88 (Body::Enum(variants))
David Tolnayb79ee962016-09-04 09:39:20 -070089));
90
David Tolnay6b7aaf02016-09-04 10:39:25 -070091named!(variant<&str, Variant>, do_parse!(
92 attrs: many0!(attribute) >>
93 ident: word >>
David Tolnayb79ee962016-09-04 09:39:20 -070094 body: alt!(
95 struct_like_body => { |fields| (Style::Struct, fields) }
96 |
97 tuple_like_body => { |fields| (Style::Tuple, fields) }
98 |
99 epsilon!() => { |_| (Style::Unit, Vec::new()) }
David Tolnay6b7aaf02016-09-04 10:39:25 -0700100 ) >>
101 (Variant {
David Tolnayb79ee962016-09-04 09:39:20 -0700102 ident: ident,
103 attrs: attrs,
104 style: body.0,
105 fields: body.1,
David Tolnay6b7aaf02016-09-04 10:39:25 -0700106 })
David Tolnayb79ee962016-09-04 09:39:20 -0700107));
108
David Tolnay6b7aaf02016-09-04 10:39:25 -0700109named!(struct_like_body<&str, Vec<Field> >, do_parse!(
110 punct!("{") >>
111 fields: separated_list!(punct!(","), struct_field) >>
112 opt!(punct!(",")) >>
113 punct!("}") >>
114 (fields)
David Tolnayb79ee962016-09-04 09:39:20 -0700115));
116
David Tolnay6b7aaf02016-09-04 10:39:25 -0700117named!(tuple_like_body<&str, Vec<Field> >, do_parse!(
118 punct!("(") >>
119 fields: separated_list!(punct!(","), tuple_field) >>
120 opt!(punct!(",")) >>
121 punct!(")") >>
122 (fields)
David Tolnayb79ee962016-09-04 09:39:20 -0700123));
124
David Tolnay6b7aaf02016-09-04 10:39:25 -0700125named!(struct_field<&str, Field>, do_parse!(
126 attrs: many0!(attribute) >>
127 vis: visibility >>
128 ident: word >>
129 punct!(":") >>
130 ty: ty >>
131 (Field {
David Tolnayb79ee962016-09-04 09:39:20 -0700132 ident: Some(ident),
133 vis: vis,
134 attrs: attrs,
135 ty: ty,
David Tolnay6b7aaf02016-09-04 10:39:25 -0700136 })
David Tolnayb79ee962016-09-04 09:39:20 -0700137));
138
David Tolnay6b7aaf02016-09-04 10:39:25 -0700139named!(tuple_field<&str, Field>, do_parse!(
140 attrs: many0!(attribute) >>
141 vis: visibility >>
142 ty: ty >>
143 (Field {
David Tolnayb79ee962016-09-04 09:39:20 -0700144 ident: None,
145 vis: vis,
146 attrs: attrs,
147 ty: ty,
David Tolnay6b7aaf02016-09-04 10:39:25 -0700148 })
David Tolnayb79ee962016-09-04 09:39:20 -0700149));