]> git.lizzy.rs Git - rust.git/blob - src/test/ui/macros/html-literals.rs
Merge commit 'f51aade56f93175dde89177a92e3669ebd8e7592' into clippyup
[rust.git] / src / test / ui / macros / html-literals.rs
1 // run-pass
2
3 #![allow(non_camel_case_types)]
4 // A test of the macro system. Can we do HTML literals?
5
6 /*
7
8 This is an HTML parser written as a macro. It's all CPS, and we have
9 to carry around a bunch of state. The arguments to macros all look like this:
10
11 { tag_stack* # expr* # tokens }
12
13 The stack keeps track of where we are in the tree. The expr is a list
14 of children of the current node. The tokens are everything that's
15 left.
16
17 */
18 use HTMLFragment::{tag, text};
19
20 macro_rules! html {
21     ( $($body:tt)* ) => (
22         parse_node!( []; []; $($body)* )
23     )
24 }
25
26 macro_rules! parse_node {
27     (
28         [:$head:ident ($(:$head_nodes:expr),*)
29          $(:$tags:ident ($(:$tag_nodes:expr),*))*];
30         [$(:$nodes:expr),*];
31         </$tag:ident> $($rest:tt)*
32     ) => (
33         parse_node!(
34             [$(: $tags ($(:$tag_nodes),*))*];
35             [$(:$head_nodes,)* :tag(stringify!($head).to_string(),
36                                     vec![$($nodes),*])];
37             $($rest)*
38         )
39     );
40
41     (
42         [$(:$tags:ident ($(:$tag_nodes:expr),*) )*];
43         [$(:$nodes:expr),*];
44         <$tag:ident> $($rest:tt)*
45     ) => (
46         parse_node!(
47             [:$tag ($(:$nodes)*) $(: $tags ($(:$tag_nodes),*) )*];
48             [];
49             $($rest)*
50         )
51     );
52
53     (
54         [$(:$tags:ident ($(:$tag_nodes:expr),*) )*];
55         [$(:$nodes:expr),*];
56         . $($rest:tt)*
57     ) => (
58         parse_node!(
59             [$(: $tags ($(:$tag_nodes),*))*];
60             [$(:$nodes,)* :text(".".to_string())];
61             $($rest)*
62         )
63     );
64
65     (
66         [$(:$tags:ident ($(:$tag_nodes:expr),*) )*];
67         [$(:$nodes:expr),*];
68         $word:ident $($rest:tt)*
69     ) => (
70         parse_node!(
71             [$(: $tags ($(:$tag_nodes),*))*];
72             [$(:$nodes,)* :text(stringify!($word).to_string())];
73             $($rest)*
74         )
75     );
76
77     ( []; [:$e:expr]; ) => ( $e );
78 }
79
80 pub fn main() {
81     let _page = html! (
82         <html>
83             <head><title>This is the title.</title></head>
84             <body>
85             <p>This is some text</p>
86             </body>
87         </html>
88     );
89 }
90
91 #[allow(unused_tuple_struct_fields)]
92 enum HTMLFragment {
93     tag(String, Vec<HTMLFragment> ),
94     text(String),
95 }