use crate::deserialize::util::{get_as_bool, make_build_fn_name, unwrap_single_member_hash}; use crate::spec::polymorphic_enum_loop_spec::{ PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopChildUseCurrent, PolymorphicEnumLoopRule, PolymorphicEnumLoopRuleBuild, PolymorphicEnumLoopRuleBuildChild, PolymorphicEnumLoopRuleChildOnEach, PolymorphicEnumLoopRulePassThrough, }; use yaml_rust2::Yaml; fn deserialize_build_child(child_name: &str, props: &Yaml) -> PolymorphicEnumLoopRuleBuildChild { if props["use_current"].is_hash() { let kind = props["use_current"]["kind"].as_str().unwrap(); PolymorphicEnumLoopRuleBuildChild::UseCurrent(PolymorphicEnumLoopChildUseCurrent::new( child_name, kind, )) } else if props["on_each"].is_hash() { let rule = props["on_each"]["rule"].as_str().unwrap(); PolymorphicEnumLoopRuleBuildChild::OnEach(PolymorphicEnumLoopRuleChildOnEach::new( child_name, rule, )) } else { panic!("Expected 'use_current' or 'on_each' hash for polymorphic enum loop build child"); } } fn deserialize_build(name: &str, props: &Yaml) -> PolymorphicEnumLoopRuleBuild { let variant = props["variant"].as_str().unwrap(); let children = props["children"] .as_vec() .unwrap() .iter() .map(|child_yaml| { let (child_name, child_props) = unwrap_single_member_hash(child_yaml); deserialize_build_child(&child_name, child_props) }) .map(Box::new) .collect(); PolymorphicEnumLoopRuleBuild::new(name, variant, children) } fn deserialize_pass_through(name: &str, props: &Yaml) -> PolymorphicEnumLoopRulePassThrough { let kind = props["kind"].as_str().unwrap(); let with = make_build_fn_name( props["with"].as_str() .unwrap_or(kind) ); PolymorphicEnumLoopRulePassThrough::new(name, kind, &with) } fn deserialize_rule(rule_name: &str, props: &Yaml) -> PolymorphicEnumLoopRule { if props["pass_through"].is_hash() { PolymorphicEnumLoopRule::PassThrough(deserialize_pass_through( rule_name, &props["pass_through"], )) } else if props["build"].is_hash() { PolymorphicEnumLoopRule::Build(deserialize_build(rule_name, &props["build"])) } else { panic!("Polymorphic enum loop rule must have 'pass_through' or 'build' hash."); } } pub fn deserialize_polymorphic_enum_loop(name: &str, props: &Yaml) -> PolymorphicEnumLoopBuildSpec { let kind = props["kind"].as_str().unwrap(); let reverse = get_as_bool(&props["reverse"]); let rules = props["rules"] .as_vec() .unwrap() .iter() .map(|rule_yaml| { let (rule_name, rule_props) = unwrap_single_member_hash(rule_yaml); deserialize_rule(&rule_name, rule_props) }) .map(Box::new) .collect(); PolymorphicEnumLoopBuildSpec::new(name, kind, reverse, rules) }