sway_parse/
generics.rs

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
39/// Parse a list of `T`s delimited by `<` and `>` and separated by `,`.
40fn 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}