forked from yewstack/yew
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhtml_block.rs
More file actions
69 lines (58 loc) · 1.94 KB
/
html_block.rs
File metadata and controls
69 lines (58 loc) · 1.94 KB
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use proc_macro2::Delimiter;
use quote::{quote, quote_spanned, ToTokens};
use syn::buffer::Cursor;
use syn::parse::{Parse, ParseStream};
use syn::{braced, token};
use super::{HtmlIterable, HtmlNode, ToNodeIterator};
use crate::PeekValue;
pub struct HtmlBlock {
pub content: BlockContent,
brace: token::Brace,
}
pub enum BlockContent {
Node(Box<HtmlNode>),
Iterable(Box<HtmlIterable>),
}
impl PeekValue<()> for HtmlBlock {
fn peek(cursor: Cursor) -> Option<()> {
cursor.group(Delimiter::Brace).map(|_| ())
}
}
impl Parse for HtmlBlock {
fn parse(input: ParseStream) -> syn::Result<Self> {
let content;
let brace = braced!(content in input);
let content = if HtmlIterable::peek(content.cursor()).is_some() {
BlockContent::Iterable(Box::new(content.parse()?))
} else {
BlockContent::Node(Box::new(content.parse()?))
};
Ok(HtmlBlock { content, brace })
}
}
impl ToTokens for HtmlBlock {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let HtmlBlock { content, .. } = self;
let new_tokens = match content {
BlockContent::Iterable(html_iterable) => quote! {#html_iterable},
BlockContent::Node(html_node) => quote! {#html_node},
};
tokens.extend(quote! {#new_tokens});
}
}
impl ToNodeIterator for HtmlBlock {
fn to_node_iterator_stream(&self) -> Option<proc_macro2::TokenStream> {
let HtmlBlock { content, brace } = self;
let new_tokens = match content {
BlockContent::Iterable(iterable) => iterable.to_node_iterator_stream(),
BlockContent::Node(node) => node.to_node_iterator_stream(),
}?;
Some(quote_spanned! {brace.span=> #new_tokens})
}
fn is_singular(&self) -> bool {
match &self.content {
BlockContent::Node(node) => node.is_singular(),
BlockContent::Iterable(_) => false,
}
}
}