1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4use syn::parse_macro_input;
5
6use xwrapup_parser::ds_node::DsRoot;
7use xwrapup_parser::ds_rune::decipher::decipher;
8use xwrapup_parser::ds_rune::DsRune;
9
10struct DefaultRune {
12 tokens: proc_macro2::TokenStream,
13 parent_name: String,
14}
15
16impl DefaultRune {
17 fn new() -> Self {
18 Self {
19 tokens: proc_macro2::TokenStream::new(),
20 parent_name: String::new(),
21 }
22 }
23}
24
25impl DsRune for DefaultRune {
26 fn inscribe_root(&mut self, parent_expr: &syn::Expr) {
27 use quote::quote;
28 self.tokens.extend(quote! {
29 println!("let parent = {:?}", #parent_expr);
30 });
31 self.parent_name = "parent".to_string();
32 }
33
34 fn inscribe_widget(
35 &mut self,
36 name: &syn::Ident,
37 attrs: &[xwrapup_parser::ds_node::ds_attr::DsAttr],
38 children: &[xwrapup_parser::ds_node::DsTreeRef],
39 ) {
40 use quote::quote;
41 let name_string = name.to_string();
42 let parent_name = &self.parent_name;
43
44 self.tokens.extend(quote! {
45 println!("let {} = obj::new({})", #name_string, #parent_name);
46 });
47
48 for attr in attrs {
49 let attr_name = attr.name.to_string();
50 let attr_value = &attr.value;
51 self.tokens.extend(quote! {
52 println!("{}.set_{}({:?})", #name_string, #attr_name, #attr_value);
53 });
54 }
55
56 let prev_parent = self.parent_name.clone();
57 self.parent_name = name_string;
58 for child in children {
59 decipher(child, self);
60 }
61 self.parent_name = prev_parent;
62 }
63
64 fn inscribe_if(
65 &mut self,
66 condition: &syn::Expr,
67 children: &[xwrapup_parser::ds_node::DsTreeRef],
68 ) {
69 use quote::quote;
70 let con = quote!(#condition).to_string();
71 self.tokens.extend(quote! {
72 println!("if {} {{", #con);
73 });
74 for child in children {
75 decipher(child, self);
76 }
77 self.tokens.extend(quote! {
78 println!("}}");
79 });
80 }
81
82 fn inscribe_iter(
83 &mut self,
84 iterable: &syn::Expr,
85 variable: &syn::Ident,
86 children: &[xwrapup_parser::ds_node::DsTreeRef],
87 ) {
88 use quote::quote;
89 let iterable_str = quote!(#iterable).to_string();
90 let variable_str = variable.to_string();
91 self.tokens.extend(quote! {
92 println!("for {} in {} {{", #variable_str, #iterable_str);
93 });
94 for child in children {
95 decipher(child, self);
96 }
97 self.tokens.extend(quote! {
98 println!("}}");
99 });
100 }
101
102 fn seal(self) -> proc_macro2::TokenStream {
103 self.tokens
104 }
105}
106
107#[proc_macro]
108pub fn ui(input: TokenStream) -> TokenStream {
109 let root = parse_macro_input!(input as DsRoot);
110
111 let mut rune = DefaultRune::new();
112
113 rune.inscribe_root(&root.get_parent());
115
116 let content = root.get_content();
118 decipher(&content, &mut rune);
119
120 TokenStream::from(rune.seal())
121}