-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
html_iterable.rs
52 lines (46 loc) · 1.5 KB
/
html_iterable.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
use crate::PeekValue;
use boolinator::Boolinator;
use proc_macro2::TokenStream;
use quote::{quote_spanned, ToTokens};
use syn::buffer::Cursor;
use syn::parse::{Parse, ParseStream, Result as ParseResult};
use syn::spanned::Spanned;
use syn::{Expr, Token};
pub struct HtmlIterable(Expr);
impl PeekValue<()> for HtmlIterable {
fn peek(cursor: Cursor) -> Option<()> {
let (ident, _) = cursor.ident()?;
(ident == "for").as_option()
}
}
impl Parse for HtmlIterable {
fn parse(input: ParseStream) -> ParseResult<Self> {
let for_token = input.parse::<Token![for]>()?;
match input.parse() {
Ok(expr) => Ok(HtmlIterable(expr)),
Err(err) => {
if err.to_string().starts_with("unexpected end of input") {
Err(syn::Error::new_spanned(
for_token,
"expected an expression after the keyword `for`",
))
} else {
Err(err)
}
}
}
}
}
impl ToTokens for HtmlIterable {
fn to_tokens(&self, tokens: &mut TokenStream) {
let expr = &self.0;
let new_tokens = quote_spanned! {expr.span()=> {
let mut __yew_vlist = ::yew::virtual_dom::VList::default();
for __yew_node in #expr {
__yew_vlist.add_child(__yew_node.into());
}
::yew::virtual_dom::VNode::from(__yew_vlist)
}};
tokens.extend(new_tokens);
}
}