1use super::*;
2use location::DynIdx;
3use proc_macro2::TokenStream as TokenStream2;
4use syn::{braced, token::Brace, Expr, Pat};
5
6#[non_exhaustive]
7#[derive(PartialEq, Eq, Clone, Debug)]
8pub struct ForLoop {
9 pub for_token: Token![for],
10 pub pat: Pat,
11 pub in_token: Token![in],
12 pub expr: Box<Expr>,
13 pub brace: Brace,
14 pub body: TemplateBody,
15 pub dyn_idx: DynIdx,
16}
17
18impl Parse for ForLoop {
19 fn parse(input: ParseStream) -> Result<Self> {
20 let for_token = input.parse()?;
23 let pat = input.call(Pat::parse_single)?;
24 let in_token = input.parse()?;
25 let expr = input.call(Expr::parse_without_eager_brace)?;
26
27 let content;
28 let brace = braced!(content in input);
29 let body = content.parse()?;
30
31 Ok(Self {
32 for_token,
33 pat,
34 in_token,
35 brace,
36 expr: Box::new(expr),
37 body,
38 dyn_idx: DynIdx::default(),
39 })
40 }
41}
42
43impl ToTokens for ForLoop {
44 fn to_tokens(&self, tokens: &mut TokenStream2) {
45 let ForLoop {
46 pat, expr, body, ..
47 } = self;
48
49 tokens.append_all(quote! {
51 {
52 let ___nodes = (#expr).into_iter().map(|#pat| { #body }).into_dyn_node();
53 ___nodes
54 }
55 });
56 }
57}
58
59#[test]
60fn parses_for_loop() {
61 let toks = quote! {
62 for item in 0..10 {
63 div { "cool-{item}" }
64 div { "cool-{item}" }
65 div { "cool-{item}" }
66 }
67 };
68
69 let for_loop: ForLoop = syn::parse2(toks).unwrap();
70 assert!(for_loop.body.roots.len() == 3);
71}