deimos-lang/ast-generator/src/deserialize/polymorphic_enum_loop_spec.rs
2025-09-25 11:57:55 -05:00

80 lines
2.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 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)
}