rune/ast/
expr_for.rs

1use crate::ast::prelude::*;
2
3#[test]
4#[cfg(not(miri))]
5fn ast_parse() {
6    rt::<ast::ExprFor>("for i in x {}");
7    rt::<ast::ExprFor>("for (a, _) in x {}");
8    rt::<ast::ExprFor>("'label: for i in x {}");
9    rt::<ast::ExprFor>("#[attr] 'label: for i in x {}");
10}
11
12/// A `for` loop over an iterator.
13///
14/// * `for <pat> in <expr> <block>`.
15#[derive(Debug, TryClone, PartialEq, Eq, ToTokens, Spanned)]
16#[non_exhaustive]
17pub struct ExprFor {
18    /// The attributes of the `for` loop
19    #[rune(iter)]
20    pub attributes: Vec<ast::Attribute>,
21    /// The label of the loop.
22    #[rune(iter)]
23    pub label: Option<(ast::Label, T![:])>,
24    /// The `for` keyword.
25    pub for_token: T![for],
26    /// The pattern binding to use.
27    /// Non-trivial pattern bindings will panic if the value doesn't match.
28    pub binding: ast::Pat,
29    /// The `in` keyword.
30    pub in_: T![in],
31    /// Expression producing the iterator.
32    pub iter: Box<ast::Expr>,
33    /// The body of the loop.
34    pub body: Box<ast::Block>,
35}
36
37impl ExprFor {
38    /// Parse with the given attributes and label.
39    pub(crate) fn parse_with_meta(
40        parser: &mut Parser<'_>,
41        attributes: Vec<ast::Attribute>,
42        label: Option<(ast::Label, T![:])>,
43    ) -> Result<Self> {
44        Ok(Self {
45            attributes,
46            label,
47            for_token: parser.parse()?,
48            binding: parser.parse()?,
49            in_: parser.parse()?,
50            iter: Box::try_new(ast::Expr::parse_without_eager_brace(parser)?)?,
51            body: Box::try_new(parser.parse()?)?,
52        })
53    }
54}
55
56expr_parse!(For, ExprFor, "for loop expression");