1use crate::{Parse, ParseResult, Parser};
2
3use sway_ast::generics::GenericParam;
4use sway_ast::keywords::{ColonToken, CommaToken, ConstToken};
5use sway_ast::punctuated::Punctuated;
6use sway_ast::{AngleBrackets, GenericArgs, GenericParams};
7use sway_types::Ident;
8
9impl Parse for GenericParam {
10 fn parse(parser: &mut Parser) -> ParseResult<Self>
11 where
12 Self: Sized,
13 {
14 if parser.peek::<ConstToken>().is_some() {
15 let _ = parser.parse::<ConstToken>()?;
16 let ident = parser.parse::<Ident>()?;
17 let _ = parser.parse::<ColonToken>()?;
18 let ty = parser.parse::<Ident>()?;
19 Ok(GenericParam::Const { ident, ty })
20 } else {
21 let ident = parser.parse::<Ident>()?;
22 Ok(GenericParam::Trait { ident })
23 }
24 }
25}
26
27impl Parse for GenericParams {
28 fn parse(parser: &mut Parser) -> ParseResult<GenericParams> {
29 parse_angle_comma(parser).map(|parameters| GenericParams { parameters })
30 }
31}
32
33impl Parse for GenericArgs {
34 fn parse(parser: &mut Parser) -> ParseResult<GenericArgs> {
35 parse_angle_comma(parser).map(|parameters| GenericArgs { parameters })
36 }
37}
38
39fn parse_angle_comma<T: Parse>(
41 parser: &mut Parser,
42) -> ParseResult<AngleBrackets<Punctuated<T, CommaToken>>> {
43 let open_angle_bracket_token = parser.parse()?;
44 let mut value_separator_pairs = Vec::new();
45 let (final_value_opt, close_angle_bracket_token) = loop {
46 if let Some(close_angle_bracket_token) = parser.take() {
47 break (None, close_angle_bracket_token);
48 };
49 let ident = parser.parse()?;
50 if let Some(close_angle_bracket_token) = parser.take() {
51 break (Some(Box::new(ident)), close_angle_bracket_token);
52 };
53 let comma_token = parser.parse()?;
54 value_separator_pairs.push((ident, comma_token));
55 };
56 let punctuated = Punctuated {
57 value_separator_pairs,
58 final_value_opt,
59 };
60 Ok(AngleBrackets {
61 open_angle_bracket_token,
62 inner: punctuated,
63 close_angle_bracket_token,
64 })
65}