sway_parse/
brackets.rs

1use crate::{Parse, ParseResult, ParseToEnd, Parser};
2
3use sway_ast::brackets::{Braces, Parens, SquareBrackets};
4use sway_ast::keywords::{CloseAngleBracketToken, OpenAngleBracketToken};
5use sway_error::handler::ErrorEmitted;
6use sway_error::parser_error::ParseErrorKind;
7use sway_types::{ast::Delimiter, Span, Spanned};
8
9pub trait ParseBracket<T>: Sized {
10    fn try_parse(parser: &mut Parser) -> ParseResult<Option<Self>>
11    where
12        T: ParseToEnd;
13
14    fn parse_all_inner(
15        parser: &mut Parser,
16        on_error: impl FnOnce(Parser) -> ErrorEmitted,
17    ) -> ParseResult<Self>
18    where
19        T: Parse;
20
21    fn try_parse_all_inner(
22        parser: &mut Parser,
23        on_error: impl FnOnce(Parser) -> ErrorEmitted,
24    ) -> ParseResult<Option<Self>>
25    where
26        T: Parse;
27}
28
29macro_rules! impl_brackets (
30    ($ty_name:ident, $delimiter:ident, $error:ident) => {
31        impl<T> ParseBracket<T> for $ty_name<T> {
32            fn try_parse(parser: &mut Parser) -> ParseResult<Option<$ty_name<T>>>
33            where
34                T: ParseToEnd
35            {
36                match parser.enter_delimited(Delimiter::$delimiter) {
37                    Some((parser, span)) => {
38                        let (inner, _consumed) = parser.parse_to_end()?;
39                        Ok(Some($ty_name { inner, span }))
40                    },
41                    None => Ok(None),
42                }
43            }
44
45            fn parse_all_inner(
46                parser: &mut Parser,
47                on_error: impl FnOnce(Parser) -> ErrorEmitted,
48            ) -> ParseResult<$ty_name<T>>
49            where
50                T: Parse
51            {
52                match parser.enter_delimited(Delimiter::$delimiter) {
53                    Some((mut parser, span)) => {
54                        let inner = parser.parse()?;
55                        if !parser.is_empty() {
56                            return Err(on_error(parser))
57                        }
58                        Ok($ty_name { inner, span })
59                    },
60                    None => Err(parser.emit_error(ParseErrorKind::$error)),
61                }
62            }
63
64            fn try_parse_all_inner(
65                parser: &mut Parser,
66                on_error: impl FnOnce(Parser) -> ErrorEmitted,
67            ) -> ParseResult<Option<$ty_name<T>>>
68            where
69                T: Parse
70            {
71                match parser.enter_delimited(Delimiter::$delimiter) {
72                    Some((mut parser, span)) => {
73                        let inner = parser.parse()?;
74                        if !parser.is_empty() {
75                            return Err(on_error(parser))
76                        }
77                        Ok(Some($ty_name { inner, span }))
78                    },
79                    None => Ok(None),
80                }
81            }
82        }
83
84        impl<T> Parse for $ty_name<T>
85        where
86            T: ParseToEnd,
87        {
88            fn parse(parser: &mut Parser) -> ParseResult<$ty_name<T>> {
89                match parser.enter_delimited(Delimiter::$delimiter) {
90                    Some((parser, span)) => {
91                        let (inner, _consumed) = parser.parse_to_end()?;
92                        Ok($ty_name { inner, span })
93                    },
94                    None => Err(parser.emit_error(ParseErrorKind::$error)),
95                }
96            }
97        }
98    };
99);
100
101impl_brackets!(Braces, Brace, ExpectedOpenBrace);
102impl_brackets!(Parens, Parenthesis, ExpectedOpenParen);
103impl_brackets!(SquareBrackets, Bracket, ExpectedOpenBracket);
104
105#[derive(Clone, Debug)]
106pub struct AngleBrackets<T> {
107    pub open_angle_bracket_token: OpenAngleBracketToken,
108    #[allow(unused)]
109    pub inner: T,
110    pub close_angle_bracket_token: CloseAngleBracketToken,
111}
112
113impl<T> Spanned for AngleBrackets<T> {
114    fn span(&self) -> Span {
115        Span::join(
116            self.open_angle_bracket_token.span(),
117            &self.close_angle_bracket_token.span(),
118        )
119    }
120}