1use std::collections::HashMap;
2
3use crate::{ast::{ParsedAttribute, ParsedEnum, ParsedField, ParsedStruct, ParsedVariant, VariantData}, token::{Delimiter, ParseError, Spacing, Span, TokenIter, TokenTree}};
4
5impl ParsedStruct {
6 pub fn parse(token_iter: &mut TokenIter) -> Result<Self, ParseError> {
7 let (name, name_span) = token_iter.expect_ident(None)?;
8 let (delimiter, fields, body_span) = token_iter.expect_group(None)?;
9 let fields: Vec<ParsedField> = match delimiter {
10 Delimiter::Brace => {
11 let mut inner_iter = TokenIter::new(fields);
12 let mut f = Vec::<ParsedField>::new();
13 while inner_iter.peek().is_some() {
14 let field = ParsedField::parse(&mut inner_iter, Delimiter::Brace)?;
15 f.push(field);
16 }
17
18 f
19 }
20 Delimiter::Parenthesis => {
21 let mut inner_iter = TokenIter::new(fields);
22 let mut f = Vec::<ParsedField>::new();
23 while inner_iter.peek().is_some() {
24 let field = ParsedField::parse(&mut inner_iter, Delimiter::Parenthesis)?;
25 f.push(field);
26 }
27
28 token_iter.expect_punct(Some(';'))?;
29
30 f
31 }
32 Delimiter::Bracket => return Err(ParseError::IncorrectDelimiter(Delimiter::Bracket, body_span)),
33 Delimiter::None => return Err(ParseError::IncorrectDelimiter(Delimiter::None, body_span))
34 };
35
36 Ok(ParsedStruct { name, fields, span: name_span })
37 }
38}
39
40impl ParsedEnum {
41 pub fn parse(token_iter: &mut TokenIter) -> Result<Self, ParseError> {
42 let (name, name_span) = token_iter.expect_ident(None)?;
43 let (delimiter, variants, body_span)= token_iter.expect_group(None)?;
44 let variants: Vec<ParsedVariant> = match delimiter {
45 Delimiter::Brace => {
46 let mut outer_iter = TokenIter::new(variants);
47 let mut v = Vec::<ParsedVariant>::new();
48 let mut index: u32 = 0;
49 while outer_iter.peek().is_some() {
50 let (name, span) = outer_iter.expect_ident(None)?;
51 if outer_iter.peek().is_none() {
52 v.push(ParsedVariant { name: name.to_owned(), index, data: VariantData::Unit(span), span });
53 }
54 else if matches!(outer_iter.peek().unwrap(), &TokenTree::Punct(',', Spacing::Alone, _)) {
55 v.push(ParsedVariant { name, index, data: VariantData::Unit(span), span });
56 }
57 else {
58 let (delimiter, fields, span) = outer_iter.expect_group(None)?;
59 let data: VariantData = match delimiter {
60 Delimiter::Parenthesis => {
61 let mut inner_iter = TokenIter::new(fields);
62 let mut f = Vec::<ParsedField>::new();
63 while inner_iter.peek().is_some() {
64 let field = ParsedField::parse(&mut inner_iter, Delimiter::Parenthesis)?;
65 f.push(field);
66 }
67
68 VariantData::Tuple(f, span)
69 }
70 Delimiter::Brace => {
71 let mut inner_iter = TokenIter::new(fields);
72 let mut f = Vec::<ParsedField>::new();
73 while inner_iter.peek().is_some() {
74 let field = ParsedField::parse(&mut inner_iter, Delimiter::Brace)?;
75 f.push(field);
76 }
77
78 VariantData::Struct(f, span)
79 }
80 Delimiter::Bracket => return Err(ParseError::IncorrectDelimiter(Delimiter::Bracket, span)),
81 Delimiter::None => return Err(ParseError::IncorrectDelimiter(Delimiter::None, span))
82 };
83
84 v.push(ParsedVariant { name, index, data, span });
85 }
86
87 if let Some(_) = outer_iter.peek() {
88 outer_iter.expect_punct(Some(','))?;
89 }
90 index += 1;
91 }
92
93 v
94 }
95 Delimiter::Parenthesis => return Err(ParseError::IncorrectDelimiter(Delimiter::Parenthesis, body_span)),
96 Delimiter::Bracket => return Err(ParseError::IncorrectDelimiter(Delimiter::Bracket, body_span)),
97 Delimiter::None => return Err(ParseError::IncorrectDelimiter(Delimiter::None, body_span))
98 };
99
100 Ok(ParsedEnum { name, variants, span: name_span })
101 }
102}
103
104impl ParsedField {
105 pub fn parse(token_iter: &mut TokenIter, delimiter: Delimiter) -> Result<Self, ParseError> {
106 match delimiter {
107 Delimiter::Brace => {
108 let mut attrs: Vec<ParsedAttribute> = Vec::new();
109 while matches!(token_iter.peek(), Some(TokenTree::Punct('#', _, _))) {
110 token_iter.next();
111 attrs.push(ParsedAttribute::parse(token_iter)?)
112 }
113 if let Some(tok) = token_iter.peek() {
114 match tok {
115 TokenTree::Ident(s, _) if s == "pub" => {
116 let _ = token_iter.next();
117 }
118 _ => ()
119 }
120 }
121 let mut ty = Vec::<TokenTree>::new();
122 let mut depth: usize = 0;
123 let (name, span) = token_iter.expect_ident(None)?;
124 token_iter.expect_punct(Some(':'))?;
125 while token_iter.peek().is_some() {
126 match token_iter.peek().unwrap() {
127 &TokenTree::Punct('<', Spacing::Alone, _) => {
128 depth += 1;
129 ty.push(token_iter.peek().unwrap().to_owned());
130 },
131 &TokenTree::Punct('>', _, span) => {
132 depth = depth.checked_sub(1).ok_or(ParseError::UnmatchedAngleBracket(span))?;
133 ty.push(token_iter.peek().unwrap().to_owned());
134 },
135 &TokenTree::Punct(',', _, _) => {
136 if depth == 0 {
137 token_iter.next();
138 break;
139 }
140 else {
141 ty.push(token_iter.peek().unwrap().to_owned());
142 }
143 },
144 _ => ty.push(token_iter.peek().unwrap().to_owned())
145 }
146
147 token_iter.next();
148 }
149
150 Ok(ParsedField { name: Some(name.to_owned()), attrs, ty, span })
151 }
152 Delimiter::Parenthesis => {
153 let mut attrs: Vec<ParsedAttribute> = Vec::new();
154 while matches!(token_iter.peek(), Some(TokenTree::Punct('#', _, _))) {
155 token_iter.next();
156 attrs.push(ParsedAttribute::parse(token_iter)?)
157 }
158 let mut ty = Vec::<TokenTree>::new();
159 let mut depth: usize = 0;
160 while token_iter.peek().is_some() {
161 match token_iter.peek().unwrap() {
162 &TokenTree::Punct('<', Spacing::Alone, _) => {
163 depth += 1;
164 ty.push(token_iter.peek().unwrap().to_owned());
165 }
166 &TokenTree::Punct('>', _, span) => {
167 depth = depth.checked_sub(1).ok_or(ParseError::UnmatchedAngleBracket(span))?;
168 ty.push(token_iter.peek().unwrap().to_owned());
169 }
170 &TokenTree::Punct(',', _, _) => {
171 if depth == 0 {
172 token_iter.next();
173 break;
174 }
175 else {
176 ty.push(token_iter.peek().unwrap().to_owned());
177 }
178 },
179 _ => ty.push(token_iter.peek().unwrap().to_owned()),
180 }
181
182 token_iter.next();
183 }
184
185 Ok(ParsedField { name: None, attrs, ty, span: Span::default()})
186 }
187 Delimiter::Bracket => return Err(ParseError::IncorrectDelimiter(Delimiter::Bracket, Span::default())),
188 Delimiter::None => return Err(ParseError::IncorrectDelimiter(Delimiter::None, Span::default()))
189 }
190 }
191}
192
193impl ParsedAttribute {
194 pub fn parse(token_iter: &mut TokenIter) -> Result<Self, ParseError> {
195 let (delimiter, body, span) = token_iter.expect_group(None)?;
196 if delimiter != Delimiter::Bracket {
197 return Err(ParseError::IncorrectDelimiter(delimiter, span));
198 }
199
200 let mut attr = TokenIter::new(body);
201 let (name, span) = attr.expect_ident(None)?;
202 let (delimiter, args_tokens, _) = attr.expect_group(None)?;
203 if delimiter != Delimiter::Parenthesis {
204 return Err(ParseError::IncorrectDelimiter(delimiter, span));
205 }
206
207 let mut args = HashMap::<String, Vec<TokenTree>>::new();
208 let mut args_iter = TokenIter::new(args_tokens);
209 while args_iter.peek().is_some() {
210 let (key, _) = args_iter.expect_ident(None)?;
211 args_iter.expect_punct(Some('='))?;
212 let mut depth: usize = 0;
213 let mut val: Vec<TokenTree> = Vec::new();
214 while args_iter.peek().is_some() {
215 match args_iter.peek().unwrap() {
216 TokenTree::Punct('<', Spacing::Alone, _) => {
217 depth += 1;
218 val.push(args_iter.peek().unwrap().to_owned());
219 }
220 TokenTree::Punct('>', _, span) => {
221 depth = depth.checked_sub(1).ok_or(ParseError::UnmatchedAngleBracket(*span))?;
222 val.push(args_iter.peek().unwrap().to_owned());
223 }
224 TokenTree::Punct(',', _, _) => {
225 if depth == 0 {
226 args_iter.next();
227 break;
228 }
229 else {
230 val.push(args_iter.peek().unwrap().to_owned());
231 }
232 }
233 _ => val.push(args_iter.peek().unwrap().to_owned()),
234 }
235
236 args_iter.next();
237 }
238
239 args.insert(key.to_owned(), val.to_owned());
240 }
241
242 Ok(ParsedAttribute { name: name, args, span })
243 }
244}