xsd_parser/optimizer/
dynamic_to_choice.rs1use crate::types::{
2 ComplexInfo, ElementInfo, ElementMode, GroupInfo, Ident, Type, TypeVariant, VecHelper,
3};
4
5use super::Optimizer;
6
7impl Optimizer {
8 #[doc = include_str!("../../tests/optimizer/abstract.xsd")]
16 #[doc = include_str!("../../tests/optimizer/expected0/convert_dynamic_to_choice.rs")]
21 #[doc = include_str!("../../tests/optimizer/expected1/convert_dynamic_to_choice.rs")]
26 pub fn convert_dynamic_to_choice(mut self) -> Self {
28 use std::collections::btree_map::Entry;
29
30 tracing::debug!("convert_dynamic_to_choice");
31
32 let idents = self
33 .types
34 .iter()
35 .filter_map(|(ident, ty)| {
36 if matches!(&ty.variant, TypeVariant::Dynamic(_)) {
37 Some(ident)
38 } else {
39 None
40 }
41 })
42 .cloned()
43 .collect::<Vec<_>>();
44
45 for ident in idents {
46 let content_name = self.types.name_builder().shared_name("Content").finish();
47 let content_ident = Ident::new(content_name).with_ns(ident.ns);
48
49 let type_ = self.types.get_mut(&ident).unwrap();
50 let TypeVariant::Dynamic(x) = &mut type_.variant else {
51 crate::unreachable!();
52 };
53
54 let mut si = GroupInfo::default();
55 for derived in &x.derived_types {
56 si.elements.find_or_insert(derived.clone(), |ident| {
57 ElementInfo::new(ident, derived.clone(), ElementMode::Element)
58 });
59 }
60
61 type_.variant = TypeVariant::ComplexType(ComplexInfo {
62 content: Some(content_ident.clone()),
63 is_dynamic: true,
64 ..Default::default()
65 });
66
67 match self.types.entry(content_ident) {
68 Entry::Vacant(e) => {
69 e.insert(Type::new(TypeVariant::Choice(si)));
70 }
71 Entry::Occupied(_) => crate::unreachable!(),
72 }
73 }
74
75 self
76 }
77}