Skip to main content

spyne_syntax/
parse.rs

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}