wright/parser/ty/
reference.rs1use crate::{
4 ast::ty::{ReferenceTy, Type},
5 lexer::token::TokenTy,
6 parser::{
7 Parser,
8 error::{ParserError, ParserErrorKind},
9 whitespace,
10 },
11 source_tracking::fragment::Fragment,
12};
13
14impl ReferenceTy {
15 pub fn parse(parser: &mut Parser) -> Result<Self, ParserError> {
21 let Some(at_symbol) = parser.next_if_is(TokenTy::At) else {
22 return Err(ParserErrorKind::ExpectedReferenceTypeSignature
23 .at(parser.peek_fragment_or_rest_cloned()));
24 };
25
26 whitespace::optional_whitespace(parser);
27
28 let referenced_type = Type::parse(parser)?;
29
30 Ok(ReferenceTy {
31 matching_source: Fragment::cover(
32 &at_symbol.fragment,
33 referenced_type.matching_source(),
34 ),
35 target_ty: Box::new(referenced_type),
36 })
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use crate::{
43 ast::ty::{AtomicTyVariant, ReferenceTy},
44 lexer::Lexer,
45 parser::Parser,
46 };
47
48 #[test]
49 fn test_reference_to_atomic() {
50 let mut parser = Parser::new(Lexer::new_test("@u64"));
51 let result = ReferenceTy::parse(&mut parser).unwrap();
52
53 assert_eq!(result.matching_source.as_str(), "@u64");
54 assert_eq!(result.target_ty.downcast_primitive().unwrap().variant, AtomicTyVariant::U64);
55 }
56
57 #[test]
58 fn test_reference_to_a_reference_to_atomic() {
59 let mut parser = Parser::new(Lexer::new_test("@@u64"));
60 let result = ReferenceTy::parse(&mut parser).unwrap();
61
62 assert_eq!(result.matching_source.as_str(), "@@u64");
63 assert!(result.target_ty.downcast_reference().is_some());
64 }
65}