Skip to main content

spyne_syntax/
parse.rs

1use crate::{ast::{ParsedEnum, ParsedField, ParsedStruct, ParsedVariant, VariantData}, token::{Delimiter, ParseError, Spacing, Span, TokenIter, TokenTree}};
2
3impl ParsedStruct {
4    pub fn parse(token_iter: &mut TokenIter) -> Result<Self, ParseError> {
5        let (name, name_span) = token_iter.expect_ident(None)?;
6        let (delimiter, fields, body_span) = token_iter.expect_group(None)?;
7        let fields: Vec<ParsedField> = match delimiter {
8            Delimiter::Brace => {
9                let mut inner_iter = TokenIter::new(fields);
10                let mut f = Vec::<ParsedField>::new();
11                while inner_iter.peek().is_some() {
12                   let field = ParsedField::parse(&mut inner_iter, Delimiter::Brace)?;
13                   f.push(field);
14                }
15                
16                f
17            }
18            Delimiter::Parenthesis => {
19                let mut inner_iter = TokenIter::new(fields);
20                let mut f = Vec::<ParsedField>::new();
21                while inner_iter.peek().is_some() {
22                    let field = ParsedField::parse(&mut inner_iter, Delimiter::Parenthesis)?;
23                    f.push(field);
24                }
25                
26                token_iter.expect_punct(Some(';'))?;
27                    
28                f
29            }
30            Delimiter::Bracket => return Err(ParseError::IncorrectDelimiter(Delimiter::Bracket, body_span)),
31            Delimiter::None => return Err(ParseError::IncorrectDelimiter(Delimiter::None, body_span))
32        };
33        
34        Ok(ParsedStruct { name, fields, span: name_span })
35    }
36}
37
38impl ParsedEnum {
39    pub fn parse(token_iter: &mut TokenIter) -> Result<Self, ParseError> {
40        let (name, name_span) = token_iter.expect_ident(None)?;
41        let (delimiter, variants, body_span)= token_iter.expect_group(None)?;
42        let variants: Vec<ParsedVariant> = match delimiter {
43            Delimiter::Brace => {
44                let mut outer_iter = TokenIter::new(variants);
45                let mut v = Vec::<ParsedVariant>::new();
46                let mut index: u32 = 0;
47                while outer_iter.peek().is_some() {
48                    let (name, span) = outer_iter.expect_ident(None)?;
49                    if outer_iter.peek().is_none() {
50                        v.push(ParsedVariant { name: name.to_owned(), index, data: VariantData::Unit(span), span });
51                    }
52                    else if matches!(outer_iter.peek().unwrap(), &TokenTree::Punct(',', Spacing::Alone, _)) {
53                        v.push(ParsedVariant { name, index, data: VariantData::Unit(span), span });
54                    }
55                    else {
56                        let (delimiter, fields, span) = outer_iter.expect_group(None)?;
57                        let data: VariantData = match delimiter {
58                            Delimiter::Parenthesis => {
59                                let mut inner_iter = TokenIter::new(fields);
60                                let mut f = Vec::<ParsedField>::new();
61                                while inner_iter.peek().is_some() {
62                                    let field = ParsedField::parse(&mut inner_iter, Delimiter::Parenthesis)?;
63                                    f.push(field);
64                                }
65                                
66                                VariantData::Tuple(f, span)
67                            }
68                            Delimiter::Brace => {
69                                let mut inner_iter = TokenIter::new(fields);
70                                let mut f = Vec::<ParsedField>::new();
71                                while inner_iter.peek().is_some() {
72                                    let field = ParsedField::parse(&mut inner_iter, Delimiter::Brace)?;
73                                    f.push(field);
74                                }
75                                
76                                VariantData::Struct(f, span)
77                            }
78                            Delimiter::Bracket => return Err(ParseError::IncorrectDelimiter(Delimiter::Bracket, span)),
79                            Delimiter::None => return Err(ParseError::IncorrectDelimiter(Delimiter::None, span))
80                        };
81                        
82                        v.push(ParsedVariant { name, index, data, span });
83                    }
84                    
85                    if let Some(_) = outer_iter.peek() {
86                        outer_iter.expect_punct(Some(','))?;
87                    }
88                    index += 1;
89                }
90                
91                v
92            }
93            Delimiter::Parenthesis => return Err(ParseError::IncorrectDelimiter(Delimiter::Parenthesis, body_span)),
94            Delimiter::Bracket => return Err(ParseError::IncorrectDelimiter(Delimiter::Bracket, body_span)),
95            Delimiter::None => return Err(ParseError::IncorrectDelimiter(Delimiter::None, body_span))
96        };
97        
98        Ok(ParsedEnum { name, variants, span: name_span })
99    }
100}
101
102impl ParsedField {
103    pub fn parse(token_iter: &mut TokenIter, delimiter: Delimiter) -> Result<Self, ParseError> {
104        match delimiter {
105            Delimiter::Brace => {
106                let mut ty = Vec::<TokenTree>::new();
107                let mut depth: usize = 0;
108                let (name, span) = token_iter.expect_ident(None)?;
109                token_iter.expect_punct(Some(':'))?;
110                while token_iter.peek().is_some() {
111                    match token_iter.peek().unwrap() {
112                        &TokenTree::Punct('<', Spacing::Alone, _) => {
113                            depth += 1;
114                            ty.push(token_iter.peek().unwrap().to_owned());
115                        },
116                        &TokenTree::Punct('>', _, span) => {
117                            depth = depth.checked_sub(1).ok_or(ParseError::UnmatchedAngleBracket(span))?;
118                            ty.push(token_iter.peek().unwrap().to_owned());
119                        },
120                        &TokenTree::Punct(',', _, _) => {
121                            if depth == 0 {
122                                token_iter.next();
123                                break;
124                            }
125                            else {
126                                ty.push(token_iter.peek().unwrap().to_owned());
127                            }
128                        },
129                        _ => ty.push(token_iter.peek().unwrap().to_owned())
130                    }
131                    
132                    token_iter.next();
133                }
134                
135                Ok(ParsedField { name: Some(name.to_owned()), ty, span })
136            }
137            Delimiter::Parenthesis => {
138                let mut ty = Vec::<TokenTree>::new();
139                let mut depth: usize = 0;
140                while token_iter.peek().is_some() {
141                    match token_iter.peek().unwrap() {
142                        &TokenTree::Punct('<', Spacing::Alone, _) => { depth += 1; ty.push(token_iter.peek().unwrap().to_owned()); }
143                        &TokenTree::Punct('>', Spacing::Alone, span) => {
144                            depth = depth.checked_sub(1).ok_or(ParseError::UnmatchedAngleBracket(span))?;
145                            ty.push(token_iter.peek().unwrap().to_owned());
146                        }
147                        &TokenTree::Punct(',', _, _) => {
148                            if depth == 0 {
149                                token_iter.next();
150                                break;
151                            }
152                            else {
153                                ty.push(token_iter.peek().unwrap().to_owned());
154                            }
155                        },
156                        _ => ty.push(token_iter.peek().unwrap().to_owned()),
157                    }
158                    
159                    token_iter.next();
160                }
161                
162                Ok(ParsedField { name: None, ty, span: Span::default()})
163            }
164            Delimiter::Bracket => return Err(ParseError::IncorrectDelimiter(Delimiter::Bracket, Span::default())),
165            Delimiter::None => return Err(ParseError::IncorrectDelimiter(Delimiter::None, Span::default()))
166        }
167    }
168}