wright/parser/ty.rs
1//! Parser implementation for parsing types.
2
3use crate::ast::ty::{AtomicTy, ReferenceTy, Type};
4
5use super::{
6 Parser,
7 error::{ParserError, ParserErrorKind},
8};
9
10mod primitive;
11mod reference;
12
13impl Type {
14 /// Parse a type signature in source code.
15 pub fn parse(parser: &mut Parser) -> Result<Self, ParserError> {
16 // Atempt to parse atomic types first -- they're the simplest. If we fail to parse, the parser doesn't advance.
17 // Since they're all keywords we don't have to worry at all about under-greedy parsing (yet).
18 if let Ok(atomic) = AtomicTy::parse(parser) {
19 return Ok(Type::Atomic(atomic));
20 }
21
22 let bytes_remaining = parser.bytes_remaining();
23
24 match ReferenceTy::parse(parser) {
25 Ok(reference_ty) => return Ok(Type::Reference(reference_ty)),
26
27 Err(err) => {
28 // If the parser was advanced in parsing the reference type, error out here.
29 if bytes_remaining != parser.bytes_remaining() {
30 return Err(
31 err.with_help("encountered error while parsing reference type signature")
32 );
33 }
34
35 // If we didn't advance we can just ignore the error and try parsing other type signature
36 // forms or fall through to the catch all "expected type signature" error (since it means
37 // we would have not seen an `@` to start a reference type signature).
38 }
39 }
40
41 Err(ParserErrorKind::ExpectedTypeSignature.at(parser.peek_fragment_or_rest_cloned()))
42 }
43}