103 lines
3.9 KiB
Rust
103 lines
3.9 KiB
Rust
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 crate::spec::{SpecialChild, SpecialChildKind, StructField};
|
|
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 if props["special"].is_hash() {
|
|
let kind = match props["special"]["kind"].as_str().unwrap() {
|
|
"range" => SpecialChildKind::Range,
|
|
"file_id" => SpecialChildKind::FileId,
|
|
_ => panic!("Unknown special child kind"),
|
|
};
|
|
PolymorphicEnumLoopRuleBuildChild::Special(SpecialChild::new(child_name, kind))
|
|
} 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();
|
|
|
|
let fields = props["fields"]
|
|
.as_vec()
|
|
.map(|fields| {
|
|
fields.iter()
|
|
.map(|field_yaml| {
|
|
let (field_name, field_props) = unwrap_single_member_hash(field_yaml);
|
|
let kind = field_props["kind"].as_str().unwrap();
|
|
StructField::new(
|
|
&field_name,
|
|
kind,
|
|
None,
|
|
false
|
|
)
|
|
})
|
|
.collect::<Vec<_>>()
|
|
})
|
|
.unwrap_or_else(|| vec![]);
|
|
|
|
PolymorphicEnumLoopRuleBuild::new(name, variant, children, fields)
|
|
}
|
|
|
|
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)
|
|
}
|