use crate::types::{
ComplexInfo, ElementInfo, ElementMode, GroupInfo, Ident, Type, TypeVariant, VecHelper,
};
use super::Optimizer;
impl Optimizer {
#[doc = include_str!("../../tests/optimizer/abstract.xsd")]
#[doc = include_str!("../../tests/optimizer/expected0/convert_dynamic_to_choice.rs")]
#[doc = include_str!("../../tests/optimizer/expected1/convert_dynamic_to_choice.rs")]
pub fn convert_dynamic_to_choice(mut self) -> Self {
use std::collections::btree_map::Entry;
tracing::debug!("convert_dynamic_to_choice");
let idents = self
.types
.iter()
.filter_map(|(ident, ty)| {
if matches!(&ty.variant, TypeVariant::Dynamic(_)) {
Some(ident)
} else {
None
}
})
.cloned()
.collect::<Vec<_>>();
for ident in idents {
let content_name = self.types.name_builder().shared_name("Content").finish();
let content_ident = Ident::new(content_name).with_ns(ident.ns);
let type_ = self.types.get_mut(&ident).unwrap();
let TypeVariant::Dynamic(x) = &mut type_.variant else {
crate::unreachable!();
};
let mut si = GroupInfo::default();
for derived in &x.derived_types {
si.elements.find_or_insert(derived.clone(), |ident| {
ElementInfo::new(ident, derived.clone(), ElementMode::Element)
});
}
type_.variant = TypeVariant::ComplexType(ComplexInfo {
content: Some(content_ident.clone()),
is_dynamic: true,
..Default::default()
});
match self.types.entry(content_ident) {
Entry::Vacant(e) => {
e.insert(Type::new(TypeVariant::Choice(si)));
}
Entry::Occupied(_) => crate::unreachable!(),
}
}
self
}
}