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