diff --git a/macro_ui/src/lib.rs b/macro_ui/src/lib.rs index aa4f752c..65fd03c0 100644 --- a/macro_ui/src/lib.rs +++ b/macro_ui/src/lib.rs @@ -37,8 +37,6 @@ fn handle_enum(name: &Ident, data: &DataEnum) -> TokenStream2 { } } - use rpg_tools_core::ui::parser::get_enum; - #[automatically_derived] impl #name { fn parse(parser: &dyn UiParser, path: &str, spaces: &str) -> #name { @@ -49,7 +47,8 @@ fn handle_enum(name: &Ident, data: &DataEnum) -> TokenStream2 { }; } - let field_quotes = visit_enum_variants(data); + let visited_fields = visit_enum_variants(data); + let parsed_fields = parse_enum_variants(name, data); quote! { #[automatically_derived] @@ -58,7 +57,7 @@ fn handle_enum(name: &Ident, data: &DataEnum) -> TokenStream2 { println!("{}Create Viewer for enum {} with path '{}'!", spaces, stringify!(#name), visitor.get_path()); visitor.enter_enum(&[#(stringify!(#variants).to_string()),*]); let inner_spaces = format!(" {}", spaces); - #field_quotes + #visited_fields visitor.leave_enum(); println!("{}Finish Viewer for enum {} with path '{}'!", spaces, stringify!(#name), visitor.get_path()); } @@ -68,12 +67,15 @@ fn handle_enum(name: &Ident, data: &DataEnum) -> TokenStream2 { impl #name { fn parse(parser: &dyn UiParser, path: &str, spaces: &str) -> #name { println!("{}Parse complex enum {} with path '{}'", spaces, stringify!(#name), path); - println!("{}type '{}'", spaces, parser.get_str(&format!("{}.type", path)).unwrap_or("")); + let t = parser.get_str(&format!("{}.type", path)).unwrap_or(""); + println!("{}type '{}'", spaces, t); - //match parser.get_str(&format!("{}.type", path)) { + match parser.get_str(&format!("{}.type", path)).unwrap_or("") { + + #parsed_fields - //} - #name::default() + _ => #name::default(), + } } } } @@ -115,6 +117,34 @@ fn visit_enum_variants(data: &DataEnum) -> TokenStream2 { quote! { #(#results)* } } +fn parse_enum_variants(name: &Ident, data: &DataEnum) -> TokenStream2 { + let mut results: Vec = Vec::new(); + + for variant in &data.variants { + let variant_name = &variant.ident; + + match &variant.fields { + Fields::Named(fields) => {} + Fields::Unnamed(fields) => { + if fields.unnamed.len() != 1 { + panic!("Tuple enums are only supported with 1 field!") + } + } + Fields::Unit => { + results.push(quote! { stringify!(#variant_name) => #name::#variant_name, }); + results.push(quote! { + println!("{}Add simple variant '{}'!", &inner_spaces, stringify!(#variant_name)); + visitor.add_unit_variant(stringify!(#variant_name)); + }); + } + } + + results.push(quote! { stringify!(#variant_name) => { } }); + } + + quote! { #(#results)* } +} + fn handle_struct(name: &Ident, fields: &FieldsNamed) -> TokenStream2 { let visited_fields: TokenStream2 = fields.named.iter().map(visit_struct_field).collect(); let parsed_fields: TokenStream2 = fields.named.iter().map(parse_struct_field).collect(); diff --git a/rpg_tools_core/examples/parser_macro.rs b/rpg_tools_core/examples/parser_macro.rs index 737d3067..2be2138d 100644 --- a/rpg_tools_core/examples/parser_macro.rs +++ b/rpg_tools_core/examples/parser_macro.rs @@ -2,6 +2,7 @@ extern crate macro_convert; extern crate rpg_tools_core; use macro_convert::Convert; +use rpg_tools_core::ui::parser::get_enum; use rpg_tools_core::ui::parser::{MockParser, UiParser}; use rpg_tools_core::ui::{UiVisitor, UI}; use std::collections::HashMap;