ara_parser/parser/internal/definition/
template.rs1use crate::lexer::token::TokenKind;
2use crate::parser::internal::definition::r#type;
3use crate::parser::internal::identifier;
4use crate::parser::internal::utils;
5use crate::parser::result::ParseResult;
6use crate::parser::state::State;
7use crate::tree::definition::template::TemplateDefinition;
8use crate::tree::definition::template::TemplateDefinitionTypeConstraint;
9use crate::tree::definition::template::TemplateDefinitionVariance;
10use crate::tree::definition::template::TemplateGroupDefinition;
11use crate::tree::definition::template::TypeTemplateGroupDefinition;
12use crate::tree::utils::CommaSeparated;
13
14pub fn template_group_definition(state: &mut State) -> ParseResult<TemplateGroupDefinition> {
15 Ok(TemplateGroupDefinition {
16 comments: state.iterator.comments(),
17 less_than: utils::skip(state, TokenKind::LessThan)?,
18 members: {
19 let mut inner = vec![];
20 let mut commas = vec![];
21
22 let mut current = state.iterator.current();
23 while current.kind != TokenKind::GreaterThan && current.kind != TokenKind::RightShift {
24 inner.push({
25 let current = state.iterator.current();
26 let variance = match ¤t.kind {
27 TokenKind::Plus => {
28 state.iterator.next();
29
30 TemplateDefinitionVariance::Covariance(current.position)
31 }
32 _ => TemplateDefinitionVariance::Invaraint,
33 };
34
35 let name = identifier::classname_identifier(state)?;
36
37 let current = state.iterator.current();
38 let constraint = match ¤t.kind {
39 TokenKind::As => TemplateDefinitionTypeConstraint::SubType(
40 utils::skip_keyword(state, TokenKind::As)?,
41 r#type::type_definition(state)?,
42 ),
43 _ => TemplateDefinitionTypeConstraint::None,
44 };
45
46 TemplateDefinition {
47 name,
48 variance,
49 constraint,
50 }
51 });
52
53 current = state.iterator.current();
54 if current.kind != TokenKind::Comma {
55 break;
56 }
57
58 commas.push(current.position);
59
60 state.iterator.next();
61 current = state.iterator.current();
62 }
63
64 CommaSeparated { inner, commas }
65 },
66 greater_than: {
67 let current = state.iterator.current();
68
69 if let Some(token) = state.ignored_shift_at {
70 utils::skip(state, TokenKind::RightShift)?;
71 state.ignored_shift_at = None;
72 token.position + 1
73 } else if current.kind == TokenKind::RightShift {
74 state.ignored_shift_at = Some(current);
75
76 current.position
77 } else {
78 utils::skip(state, TokenKind::GreaterThan)?
79 }
80 },
81 })
82}
83
84pub fn type_template_group_definition(
85 state: &mut State,
86) -> ParseResult<TypeTemplateGroupDefinition> {
87 let comments = state.iterator.comments();
88 let less_than = utils::skip(state, TokenKind::LessThan)?;
89
90 let members = {
91 let mut inner = vec![];
92 let mut commas = vec![];
93
94 let mut current = state.iterator.current();
95 while current.kind != TokenKind::GreaterThan && current.kind != TokenKind::RightShift {
96 inner.push(r#type::type_definition(state)?);
97
98 current = state.iterator.current();
99 if current.kind != TokenKind::Comma {
100 break;
101 }
102
103 commas.push(current.position);
104
105 state.iterator.next();
106 current = state.iterator.current();
107 }
108
109 CommaSeparated { inner, commas }
110 };
111
112 let greater_than = {
113 let current = state.iterator.current();
114
115 if let Some(token) = state.ignored_shift_at {
116 utils::skip(state, TokenKind::RightShift)?;
117 state.ignored_shift_at = None;
118 token.position + 1
119 } else if current.kind == TokenKind::RightShift {
120 state.ignored_shift_at = Some(current);
121
122 current.position
123 } else {
124 utils::skip(state, TokenKind::GreaterThan)?
125 }
126 };
127
128 Ok(TypeTemplateGroupDefinition {
129 comments,
130 less_than,
131 members,
132 greater_than,
133 })
134}