This is unreleased documentation for Yew Next version.
For up-to-date documentation, see the latest version on docs.rs.

yew_macro/html_tree/
html_iterable.rs

1use proc_macro2::TokenStream;
2use quote::{quote_spanned, ToTokens};
3use syn::buffer::Cursor;
4use syn::parse::{Parse, ParseStream};
5use syn::spanned::Spanned;
6use syn::{Expr, Token};
7
8use super::ToNodeIterator;
9use crate::PeekValue;
10
11pub struct HtmlIterable(Expr);
12
13impl PeekValue<()> for HtmlIterable {
14    fn peek(cursor: Cursor) -> Option<()> {
15        let (ident, _) = cursor.ident()?;
16        (ident == "for").then_some(())
17    }
18}
19
20impl Parse for HtmlIterable {
21    fn parse(input: ParseStream) -> syn::Result<Self> {
22        let for_token = input.parse::<Token![for]>()?;
23
24        match input.parse() {
25            Ok(expr) => Ok(HtmlIterable(expr)),
26            Err(err) => {
27                if err.to_string().starts_with("unexpected end of input") {
28                    Err(syn::Error::new_spanned(
29                        for_token,
30                        "expected an expression after the keyword `for`",
31                    ))
32                } else {
33                    Err(err)
34                }
35            }
36        }
37    }
38}
39
40impl ToTokens for HtmlIterable {
41    fn to_tokens(&self, tokens: &mut TokenStream) {
42        let expr = &self.0;
43        let new_tokens = quote_spanned! {expr.span()=>
44            #[allow(unused_braces)]
45            ::std::iter::Iterator::collect::<::yew::virtual_dom::VNode>(::std::iter::IntoIterator::into_iter(#expr))
46        };
47
48        tokens.extend(new_tokens);
49    }
50}
51
52impl ToNodeIterator for HtmlIterable {
53    fn to_node_iterator_stream(&self) -> Option<TokenStream> {
54        let Self(expr) = self;
55        // #expr can return anything that implements IntoIterator<Item=Into<T>>
56        // We use a util method to avoid clippy warnings and reduce generated code size
57        Some(quote_spanned! {expr.span()=>
58            ::yew::utils::into_node_iter(#expr)
59        })
60    }
61}