1use erl_tokenize::tokens::{KeywordToken, SymbolToken};
2use erl_tokenize::values::{Keyword, Symbol};
3use erl_tokenize::{Position, PositionRange};
4
5use self::parts::{Body, Qualifier, Timeout, TryAfter, TryCatch, TryOf};
6use crate::cst::clauses::{CaseClause, FunClause, IfClause, NamedFunClause};
7use crate::cst::commons::parts::{Clauses, ModulePrefix, NameAndArity, Sequence};
8use crate::cst::commons::{self, AtomOrVariable, IntegerOrVariable};
9use crate::cst::Expr;
10use crate::traits::{Parse, ParseTail, TokenRead};
11use crate::{Parser, Result};
12
13pub mod parts;
14
15pub type Tuple = commons::Tuple<Expr>;
16pub type Map = commons::Map<Expr>;
17pub type Record = commons::Record<Expr>;
18pub type RecordFieldIndex = commons::RecordFieldIndex;
19pub type List = commons::List<Expr>;
20pub type Bits = commons::Bits<Expr>;
21pub type Parenthesized = commons::Parenthesized<Expr>;
22pub type FunCall = commons::Call<Expr>;
23pub type UnaryOpCall = commons::UnaryOpCall<Expr>;
24pub type BinaryOpCall = commons::BinaryOpCall<Expr>;
25pub type Match = commons::Match<Expr>;
26
27#[derive(Debug, Clone)]
29pub struct MapUpdate {
30 pub map: Expr,
31 pub update: Map,
32}
33impl ParseTail for MapUpdate {
34 type Head = Expr;
35 fn parse_tail<T: TokenRead>(parser: &mut Parser<T>, head: Self::Head) -> Result<Self> {
36 Ok(MapUpdate {
37 map: head,
38 update: track!(parser.parse())?,
39 })
40 }
41}
42impl PositionRange for MapUpdate {
43 fn start_position(&self) -> Position {
44 self.map.start_position()
45 }
46 fn end_position(&self) -> Position {
47 self.update.end_position()
48 }
49}
50
51#[derive(Debug, Clone)]
53pub struct RecordUpdate {
54 pub record: Expr,
55 pub update: Record,
56}
57impl ParseTail for RecordUpdate {
58 type Head = Expr;
59 fn parse_tail<T: TokenRead>(parser: &mut Parser<T>, head: Self::Head) -> Result<Self> {
60 Ok(RecordUpdate {
61 record: head,
62 update: track!(parser.parse())?,
63 })
64 }
65}
66impl PositionRange for RecordUpdate {
67 fn start_position(&self) -> Position {
68 self.record.start_position()
69 }
70 fn end_position(&self) -> Position {
71 self.update.end_position()
72 }
73}
74
75#[derive(Debug, Clone)]
77pub struct Try {
78 pub _try: KeywordToken,
79 pub body: Body,
80 pub branch: Option<TryOf>,
81 pub catch: Option<TryCatch>,
82 pub after: Option<TryAfter>,
83 pub _end: KeywordToken,
84}
85impl Parse for Try {
86 fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
87 Ok(Try {
88 _try: track!(parser.expect(&Keyword::Try))?,
89 body: track!(parser.parse())?,
90 branch: track!(parser.parse())?,
91 catch: track!(parser.parse())?,
92 after: track!(parser.parse())?,
93 _end: track!(parser.expect(&Keyword::End))?,
94 })
95 }
96}
97impl PositionRange for Try {
98 fn start_position(&self) -> Position {
99 self._try.start_position()
100 }
101 fn end_position(&self) -> Position {
102 self._end.end_position()
103 }
104}
105
106#[derive(Debug, Clone)]
108pub struct Receive {
109 pub _receive: KeywordToken,
110 pub clauses: Clauses<CaseClause>,
111 pub timeout: Option<Timeout>,
112 pub _end: KeywordToken,
113}
114impl Parse for Receive {
115 fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
116 Ok(Receive {
117 _receive: track!(parser.expect(&Keyword::Receive))?,
118 clauses: track!(parser.parse())?,
119 timeout: track!(parser.parse())?,
120 _end: track!(parser.expect(&Keyword::End))?,
121 })
122 }
123}
124impl PositionRange for Receive {
125 fn start_position(&self) -> Position {
126 self._receive.start_position()
127 }
128 fn end_position(&self) -> Position {
129 self._end.end_position()
130 }
131}
132
133#[derive(Debug, Clone)]
135pub struct If {
136 pub _if: KeywordToken,
137 pub clauses: Clauses<IfClause>,
138 pub _end: KeywordToken,
139}
140impl Parse for If {
141 fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
142 Ok(If {
143 _if: track!(parser.expect(&Keyword::If))?,
144 clauses: track!(parser.parse())?,
145 _end: track!(parser.expect(&Keyword::End))?,
146 })
147 }
148}
149impl PositionRange for If {
150 fn start_position(&self) -> Position {
151 self._if.start_position()
152 }
153 fn end_position(&self) -> Position {
154 self._end.end_position()
155 }
156}
157
158#[derive(Debug, Clone)]
160pub struct Case {
161 pub _case: KeywordToken,
162 pub expr: Expr,
163 pub _of: KeywordToken,
164 pub clauses: Clauses<CaseClause>,
165 pub _end: KeywordToken,
166}
167impl Parse for Case {
168 fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
169 Ok(Case {
170 _case: track!(parser.expect(&Keyword::Case))?,
171 expr: track!(parser.parse())?,
172 _of: track!(parser.expect(&Keyword::Of))?,
173 clauses: track!(parser.parse())?,
174 _end: track!(parser.expect(&Keyword::End))?,
175 })
176 }
177}
178impl PositionRange for Case {
179 fn start_position(&self) -> Position {
180 self._case.start_position()
181 }
182 fn end_position(&self) -> Position {
183 self._end.end_position()
184 }
185}
186
187#[derive(Debug, Clone)]
189#[allow(clippy::large_enum_variant)]
190pub enum Fun {
191 Defined(DefinedFun),
192 Anonymous(AnonymousFun),
193 Named(NamedFun),
194}
195impl Parse for Fun {
196 fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
197 if let Ok(x) = parser.transaction(Parser::parse) {
199 Ok(Fun::Defined(x))
200 } else if let Ok(x) = parser.transaction(Parser::parse) {
201 Ok(Fun::Anonymous(x))
202 } else {
203 Ok(Fun::Named(track!(parser.parse())?))
204 }
205 }
206}
207impl PositionRange for Fun {
208 fn start_position(&self) -> Position {
209 match *self {
210 Fun::Defined(ref x) => x.start_position(),
211 Fun::Anonymous(ref x) => x.start_position(),
212 Fun::Named(ref x) => x.start_position(),
213 }
214 }
215 fn end_position(&self) -> Position {
216 match *self {
217 Fun::Defined(ref x) => x.end_position(),
218 Fun::Anonymous(ref x) => x.end_position(),
219 Fun::Named(ref x) => x.end_position(),
220 }
221 }
222}
223
224#[derive(Debug, Clone)]
226pub struct DefinedFun {
227 pub _fun: KeywordToken,
228 pub module: Option<ModulePrefix<AtomOrVariable>>,
229 pub fun: NameAndArity<AtomOrVariable, IntegerOrVariable>,
230}
231impl Parse for DefinedFun {
232 fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
233 Ok(DefinedFun {
234 _fun: track!(parser.expect(&Keyword::Fun))?,
235 module: track!(parser.parse())?,
236 fun: track!(parser.parse())?,
237 })
238 }
239}
240impl PositionRange for DefinedFun {
241 fn start_position(&self) -> Position {
242 self._fun.start_position()
243 }
244 fn end_position(&self) -> Position {
245 self.fun.end_position()
246 }
247}
248
249#[derive(Debug, Clone)]
251pub struct AnonymousFun {
252 pub _fun: KeywordToken,
253 pub clauses: Clauses<FunClause>,
254 pub _end: KeywordToken,
255}
256impl Parse for AnonymousFun {
257 fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
258 Ok(AnonymousFun {
259 _fun: track!(parser.expect(&Keyword::Fun))?,
260 clauses: track!(parser.parse())?,
261 _end: track!(parser.expect(&Keyword::End))?,
262 })
263 }
264}
265impl PositionRange for AnonymousFun {
266 fn start_position(&self) -> Position {
267 self._fun.start_position()
268 }
269 fn end_position(&self) -> Position {
270 self._end.end_position()
271 }
272}
273
274#[derive(Debug, Clone)]
276pub struct NamedFun {
277 pub _fun: KeywordToken,
278 pub clauses: Clauses<NamedFunClause>,
279 pub _end: KeywordToken,
280}
281impl Parse for NamedFun {
282 fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
283 Ok(NamedFun {
284 _fun: track!(parser.expect(&Keyword::Fun))?,
285 clauses: track!(parser.parse())?,
286 _end: track!(parser.expect(&Keyword::End))?,
287 })
288 }
289}
290impl PositionRange for NamedFun {
291 fn start_position(&self) -> Position {
292 self._fun.start_position()
293 }
294 fn end_position(&self) -> Position {
295 self._end.end_position()
296 }
297}
298
299#[derive(Debug, Clone)]
301pub struct ListComprehension {
302 pub _open: SymbolToken,
303 pub element: Expr,
304 pub _bar: SymbolToken,
305 pub qualifiers: Sequence<Qualifier>,
306 pub _close: SymbolToken,
307}
308impl Parse for ListComprehension {
309 fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
310 Ok(ListComprehension {
311 _open: track!(parser.expect(&Symbol::OpenSquare))?,
312 element: track!(parser.parse())?,
313 _bar: track!(parser.expect(&Symbol::DoubleVerticalBar))?,
314 qualifiers: track!(parser.parse())?,
315 _close: track!(parser.expect(&Symbol::CloseSquare))?,
316 })
317 }
318}
319impl PositionRange for ListComprehension {
320 fn start_position(&self) -> Position {
321 self._open.start_position()
322 }
323 fn end_position(&self) -> Position {
324 self._close.end_position()
325 }
326}
327
328#[derive(Debug, Clone)]
330pub struct BitsComprehension {
331 pub _open: SymbolToken,
332 pub element: Expr,
333 pub _bar: SymbolToken,
334 pub qualifiers: Sequence<Qualifier>,
335 pub _close: SymbolToken,
336}
337impl Parse for BitsComprehension {
338 fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
339 Ok(BitsComprehension {
340 _open: track!(parser.expect(&Symbol::DoubleLeftAngle))?,
341 element: track!(parser.parse())?,
342 _bar: track!(parser.expect(&Symbol::DoubleVerticalBar))?,
343 qualifiers: track!(parser.parse())?,
344 _close: track!(parser.expect(&Symbol::DoubleRightAngle))?,
345 })
346 }
347}
348impl PositionRange for BitsComprehension {
349 fn start_position(&self) -> Position {
350 self._open.start_position()
351 }
352 fn end_position(&self) -> Position {
353 self._close.end_position()
354 }
355}
356
357#[derive(Debug, Clone)]
359pub struct Catch {
360 pub _catch: KeywordToken,
361 pub expr: Body,
362}
363impl Parse for Catch {
364 fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
365 Ok(Catch {
366 _catch: track!(parser.expect(&Keyword::Catch))?,
367 expr: track!(parser.parse())?,
368 })
369 }
370}
371impl PositionRange for Catch {
372 fn start_position(&self) -> Position {
373 self._catch.start_position()
374 }
375 fn end_position(&self) -> Position {
376 self.expr.end_position()
377 }
378}
379
380#[derive(Debug, Clone)]
382pub struct Block {
383 pub _begin: KeywordToken,
384 pub body: Body,
385 pub _end: KeywordToken,
386}
387impl Parse for Block {
388 fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
389 Ok(Block {
390 _begin: track!(parser.expect(&Keyword::Begin))?,
391 body: track!(parser.parse())?,
392 _end: track!(parser.expect(&Keyword::End))?,
393 })
394 }
395}
396impl PositionRange for Block {
397 fn start_position(&self) -> Position {
398 self._begin.start_position()
399 }
400 fn end_position(&self) -> Position {
401 self._end.end_position()
402 }
403}
404
405#[derive(Debug, Clone)]
407pub struct RecordFieldAccess<T = Expr> {
408 pub record: T,
409 pub index: RecordFieldIndex,
410}
411impl<T> ParseTail for RecordFieldAccess<T> {
412 type Head = T;
413 fn parse_tail<U: TokenRead>(parser: &mut Parser<U>, head: Self::Head) -> Result<Self> {
414 Ok(RecordFieldAccess {
415 record: head,
416 index: track!(parser.parse())?,
417 })
418 }
419}
420impl<T: PositionRange> PositionRange for RecordFieldAccess<T> {
421 fn start_position(&self) -> Position {
422 self.record.start_position()
423 }
424 fn end_position(&self) -> Position {
425 self.index.end_position()
426 }
427}