1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7enum SimpleTypePhase {
8 Annotation,
10 Derivation,
12 Done,
14}
15
16pub struct SimpleTypeFrame {
18 phase: SimpleTypePhase,
19 name: Option<NameId>,
20 final_derivation: Option<DerivationSet>,
21 id: Option<String>,
22 derivation_id: Option<String>,
23 variety: Option<SimpleTypeVariety>,
24 base_type: Option<TypeRefResult>,
25 item_type: Option<TypeRefResult>,
26 member_types: Vec<TypeRefResult>,
27 facets: FacetSet,
28 annotation: Option<Annotation>,
29 source: Option<SourceRef>,
30 foreign_attributes: Vec<ForeignAttribute>,
31}
32
33impl SimpleTypeFrame {
34 pub fn new(
35 attrs: &AttributeMap,
36 name_table: &NameTable,
37 source: Option<SourceRef>,
38 ) -> SchemaResult<Self> {
39 let name = attrs
40 .get_value_by_name(name_table, "name")
41 .and_then(|s| name_table.get(s));
42
43 let final_derivation = parse_derivation_set_opt(
44 attrs.get_value_by_name(name_table, "final"),
45 )?;
46
47 let id = attrs
48 .get_value_by_name(name_table, "id")
49 .map(String::from);
50
51 Ok(Self {
52 phase: SimpleTypePhase::Annotation,
53 name,
54 final_derivation,
55 id,
56 derivation_id: None,
57 variety: None,
58 base_type: None,
59 item_type: None,
60 member_types: Vec::new(),
61 facets: FacetSet::new(),
62 annotation: None,
63 source,
64 foreign_attributes: Vec::new(),
65 })
66 }
67}
68
69impl Frame for SimpleTypeFrame {
70 fn allows(&self, local_name: &str, _name_table: &NameTable) -> bool {
71 match self.phase {
72 SimpleTypePhase::Annotation => matches!(
73 local_name,
74 xsd_names::ANNOTATION | xsd_names::RESTRICTION | xsd_names::LIST | xsd_names::UNION
75 ),
76 SimpleTypePhase::Derivation => matches!(
77 local_name,
78 xsd_names::RESTRICTION | xsd_names::LIST | xsd_names::UNION
79 ),
80 SimpleTypePhase::Done => false,
81 }
82 }
83
84 fn allows_attribute(&self, local_name: &str, _name_table: &NameTable) -> bool {
85 matches!(local_name, "name" | "final" | "id")
86 }
87
88 fn on_child_start(&mut self, local_name: &str, _name_table: &NameTable) {
89 match local_name {
90 xsd_names::ANNOTATION => {
91 self.phase = SimpleTypePhase::Derivation;
92 }
93 xsd_names::RESTRICTION | xsd_names::LIST | xsd_names::UNION => {
94 self.phase = SimpleTypePhase::Done;
95 }
96 _ => {}
97 }
98 }
99
100 fn attach(&mut self, child: FrameResult) -> SchemaResult<()> {
101 match child {
102 FrameResult::Annotation(ann) => {
103 self.annotation = Some(ann);
104 }
105 FrameResult::Type(TypeFrameResult::Simple(st)) => {
106 self.variety = Some(st.variety);
108 self.base_type = st.base_type;
109 self.item_type = st.item_type;
110 self.member_types = st.member_types;
111 self.facets = st.facets;
112 self.derivation_id = st.derivation_id;
113 }
114 FrameResult::Restriction(res) => {
115 if res.base_type.is_some() && res.inline_type.is_some() {
118 return Err(SchemaError::structural(
119 "src-restriction-base-or-simpleType",
120 "Simple type restriction cannot have both 'base' attribute and inline type",
121 None,
122 ));
123 }
124 let base = if let Some(inline) = res.inline_type.clone() {
125 Some(TypeRefResult::Inline(Box::new(TypeFrameResult::Simple(Box::new(inline)))))
126 } else {
127 res.base_type.clone()
128 };
129 self.variety = Some(SimpleTypeVariety::Atomic);
130 self.base_type = base;
131 self.facets = res.facets.clone();
132 self.derivation_id = res.id.clone();
133 }
134 FrameResult::Skip => {}
135 _ => {}
136 }
137 Ok(())
138 }
139
140 fn finish(self: Box<Self>) -> SchemaResult<FrameResult> {
141 if self.variety.is_none() {
146 return Err(SchemaError::structural(
147 "src-simple-type",
148 "simpleType must contain one of <restriction>, <list>, or <union>",
149 None,
150 ));
151 }
152 let annotation = merge_foreign_attributes(
153 self.annotation,
154 self.foreign_attributes,
155 self.source.clone(),
156 );
157 Ok(FrameResult::Type(TypeFrameResult::Simple(Box::new(SimpleTypeResult {
158 name: self.name,
159 variety: self.variety.unwrap_or(SimpleTypeVariety::Atomic),
160 base_type: self.base_type,
161 item_type: self.item_type,
162 member_types: self.member_types,
163 facets: self.facets,
164 final_derivation: self.final_derivation,
165 id: self.id,
166 derivation_id: self.derivation_id,
167 annotation,
168 source: self.source,
169 }))))
170 }
171
172 fn has_annotation(&self) -> bool {
173 self.annotation.is_some()
174 }
175
176 fn source(&self) -> Option<&SourceRef> {
177 self.source.as_ref()
178 }
179
180 fn set_foreign_attributes(&mut self, attrs: Vec<ForeignAttribute>) {
181 self.foreign_attributes = attrs;
182 }
183}
184
185#[derive(Debug, Clone, Copy, PartialEq, Eq)]
192enum RestrictionPhase {
193 Annotation,
194 Content,
195 Facets,
196 Attributes,
197 Done,
198}
199
200pub struct RestrictionFrame {
201 phase: RestrictionPhase,
202 base_type: Option<TypeRefResult>,
203 facets: FacetSet,
204 particle: Option<ParticleResult>,
205 open_content: Option<OpenContentResult>,
206 attributes: Vec<AttributeUseResult>,
207 attribute_groups: Vec<QNameRef>,
208 attribute_wildcard: Option<WildcardResult>,
209 assertions: Vec<AssertResult>,
210 id: Option<String>,
211 annotation: Option<Annotation>,
212 inline_type: Option<SimpleTypeResult>,
213 source: Option<SourceRef>,
214 foreign_attributes: Vec<ForeignAttribute>,
215}
216
217impl RestrictionFrame {
218 pub fn new(
219 attrs: &AttributeMap,
220 name_table: &NameTable,
221 source: Option<SourceRef>,
222 ns_snapshot: &NamespaceContextSnapshot,
223 ) -> SchemaResult<Self> {
224 let base_type = attrs
225 .get_value_by_name(name_table, "base")
226 .map(|s| parse_qname_ref(s, name_table, ns_snapshot))
227 .transpose()?
228 .map(TypeRefResult::QName);
229
230 let id = attrs
231 .get_value_by_name(name_table, "id")
232 .map(String::from);
233
234 Ok(Self {
235 phase: RestrictionPhase::Annotation,
236 base_type,
237 facets: FacetSet::new(),
238 particle: None,
239 open_content: None,
240 attributes: Vec::new(),
241 attribute_groups: Vec::new(),
242 attribute_wildcard: None,
243 assertions: Vec::new(),
244 id,
245 annotation: None,
246 inline_type: None,
247 source,
248 foreign_attributes: Vec::new(),
249 })
250 }
251}
252
253impl Frame for RestrictionFrame {
254 fn allows(&self, local_name: &str, _name_table: &NameTable) -> bool {
255 let is_facet = matches!(
256 local_name,
257 xsd_names::ENUMERATION
258 | xsd_names::PATTERN
259 | xsd_names::MIN_INCLUSIVE
260 | xsd_names::MAX_INCLUSIVE
261 | xsd_names::MIN_EXCLUSIVE
262 | xsd_names::MAX_EXCLUSIVE
263 | xsd_names::MIN_LENGTH
264 | xsd_names::MAX_LENGTH
265 | xsd_names::LENGTH
266 | xsd_names::TOTAL_DIGITS
267 | xsd_names::FRACTION_DIGITS
268 | xsd_names::WHITE_SPACE
269 );
270
271 #[cfg(feature = "xsd11")]
272 let is_xsd11_element = matches!(
273 local_name,
274 xsd_names::OPEN_CONTENT
275 | xsd_names::ASSERT
276 | xsd_names::ASSERTION
277 | xsd_names::EXPLICIT_TIMEZONE
278 );
279 #[cfg(not(feature = "xsd11"))]
280 let is_xsd11_element = false;
281
282 #[cfg(feature = "xsd11")]
283 let is_xsd11_facet = matches!(
284 local_name,
285 xsd_names::ASSERTION | xsd_names::EXPLICIT_TIMEZONE
286 );
287 #[cfg(not(feature = "xsd11"))]
288 let is_xsd11_facet = false;
289
290 match self.phase {
291 RestrictionPhase::Annotation => matches!(
292 local_name,
293 xsd_names::ANNOTATION
294 | xsd_names::SIMPLE_TYPE
295 | xsd_names::SEQUENCE
296 | xsd_names::CHOICE
297 | xsd_names::ALL
298 | xsd_names::GROUP
299 | xsd_names::ATTRIBUTE
300 | xsd_names::ATTRIBUTE_GROUP
301 | xsd_names::ANY_ATTRIBUTE
302 ) || is_facet || is_xsd11_element,
303 RestrictionPhase::Content => matches!(
304 local_name,
305 xsd_names::SIMPLE_TYPE
306 | xsd_names::SEQUENCE
307 | xsd_names::CHOICE
308 | xsd_names::ALL
309 | xsd_names::GROUP
310 | xsd_names::ATTRIBUTE
311 | xsd_names::ATTRIBUTE_GROUP
312 | xsd_names::ANY_ATTRIBUTE
313 ) || is_facet || is_xsd11_element,
314 RestrictionPhase::Facets => is_facet || is_xsd11_facet || matches!(
315 local_name,
316 xsd_names::ATTRIBUTE
317 | xsd_names::ATTRIBUTE_GROUP
318 | xsd_names::ANY_ATTRIBUTE
319 ) || matches!(local_name, xsd_names::ASSERT | xsd_names::OPEN_CONTENT if is_xsd11_element),
320 RestrictionPhase::Attributes => matches!(
321 local_name,
322 xsd_names::ATTRIBUTE
323 | xsd_names::ATTRIBUTE_GROUP
324 | xsd_names::ANY_ATTRIBUTE
325 ) || is_xsd11_element,
326 RestrictionPhase::Done => false,
327 }
328 }
329
330 fn allows_attribute(&self, local_name: &str, _name_table: &NameTable) -> bool {
331 matches!(local_name, "base" | "id")
332 }
333
334 fn on_child_start(&mut self, local_name: &str, _name_table: &NameTable) {
335 match local_name {
336 xsd_names::ANNOTATION => {
337 self.phase = RestrictionPhase::Content;
338 }
339 xsd_names::SIMPLE_TYPE => {
340 self.phase = RestrictionPhase::Facets;
341 }
342 xsd_names::SEQUENCE | xsd_names::CHOICE | xsd_names::ALL | xsd_names::GROUP => {
343 self.phase = RestrictionPhase::Attributes;
344 }
345 xsd_names::ENUMERATION | xsd_names::PATTERN | xsd_names::MIN_INCLUSIVE
346 | xsd_names::MAX_INCLUSIVE | xsd_names::MIN_EXCLUSIVE | xsd_names::MAX_EXCLUSIVE
347 | xsd_names::MIN_LENGTH | xsd_names::MAX_LENGTH | xsd_names::LENGTH
348 | xsd_names::TOTAL_DIGITS | xsd_names::FRACTION_DIGITS | xsd_names::WHITE_SPACE => {
349 self.phase = RestrictionPhase::Facets;
350 }
351 xsd_names::ATTRIBUTE | xsd_names::ATTRIBUTE_GROUP => {
352 self.phase = RestrictionPhase::Attributes;
353 }
354 xsd_names::ANY_ATTRIBUTE => {
355 self.phase = RestrictionPhase::Done;
356 }
357 _ => {}
358 }
359 }
360
361 fn attach(&mut self, child: FrameResult) -> SchemaResult<()> {
362 match child {
363 FrameResult::Annotation(ann) => {
364 self.annotation = Some(ann);
365 }
366 FrameResult::Type(TypeFrameResult::Simple(st)) => {
367 self.inline_type = Some(*st);
368 }
369 FrameResult::Facet(facet) => {
370 apply_facet(&mut self.facets, facet)?;
371 }
372 FrameResult::Particle(particle) => {
373 self.particle = Some(particle);
374 }
375 FrameResult::OpenContent(open_content) => {
376 self.open_content = Some(open_content);
377 }
378 FrameResult::Attribute(attr) => {
379 let use_kind = match attr.use_kind.as_deref() {
380 Some("required") => AttributeUseKind::Required,
381 Some("prohibited") => AttributeUseKind::Prohibited,
382 _ => AttributeUseKind::Optional,
383 };
384 self.attributes.push(AttributeUseResult {
385 attribute: attr,
386 use_kind,
387 });
388 }
389 FrameResult::Group(GroupFrameResult::Attribute(ag)) => {
390 if let Some(ref_name) = ag.ref_name {
391 self.attribute_groups.push(ref_name);
392 }
393 }
394 FrameResult::Group(GroupFrameResult::Model(mg)) => {
395 let min_occurs = mg.min_occurs;
396 let max_occurs = mg.max_occurs;
397 self.particle = Some(ParticleResult {
398 term: ParticleTerm::Group(*mg),
399 min_occurs,
400 max_occurs,
401 source: None,
402 });
403 }
404 FrameResult::Wildcard(wc) => {
405 self.attribute_wildcard = Some(wc);
406 }
407 FrameResult::Assert(assertion) => {
408 self.assertions.push(assertion);
409 }
410 FrameResult::Skip => {}
411 _ => {}
412 }
413 Ok(())
414 }
415
416 fn finish(self: Box<Self>) -> SchemaResult<FrameResult> {
417 let annotation = merge_foreign_attributes(
423 self.annotation,
424 self.foreign_attributes,
425 self.source.clone(),
426 );
427 Ok(FrameResult::Restriction(Box::new(RestrictionResult {
428 base_type: self.base_type,
429 inline_type: self.inline_type,
430 facets: self.facets,
431 particle: self.particle,
432 open_content: self.open_content,
433 attributes: self.attributes,
434 attribute_groups: self.attribute_groups,
435 attribute_wildcard: self.attribute_wildcard,
436 assertions: self.assertions,
437 id: self.id,
438 annotation,
439 source: self.source,
440 })))
441 }
442
443 fn has_annotation(&self) -> bool {
444 self.annotation.is_some()
445 }
446
447 fn source(&self) -> Option<&SourceRef> {
448 self.source.as_ref()
449 }
450
451 fn set_foreign_attributes(&mut self, attrs: Vec<ForeignAttribute>) {
452 self.foreign_attributes = attrs;
453 }
454}
455
456#[derive(Debug, Clone, Copy, PartialEq, Eq)]
463enum ExtensionPhase {
464 Annotation,
465 Content,
466 Attributes,
467 Done,
468}
469
470pub struct ExtensionFrame {
471 phase: ExtensionPhase,
472 base_type: Option<TypeRefResult>,
473 particle: Option<ParticleResult>,
474 open_content: Option<OpenContentResult>,
475 attributes: Vec<AttributeUseResult>,
476 attribute_groups: Vec<QNameRef>,
477 attribute_wildcard: Option<WildcardResult>,
478 assertions: Vec<AssertResult>,
479 id: Option<String>,
480 annotation: Option<Annotation>,
481 source: Option<SourceRef>,
482 foreign_attributes: Vec<ForeignAttribute>,
483}
484
485impl ExtensionFrame {
486 pub fn new(
487 attrs: &AttributeMap,
488 name_table: &NameTable,
489 source: Option<SourceRef>,
490 ns_snapshot: &NamespaceContextSnapshot,
491 ) -> SchemaResult<Self> {
492 let base_type = attrs
493 .get_value_by_name(name_table, "base")
494 .map(|s| parse_qname_ref(s, name_table, ns_snapshot))
495 .transpose()?
496 .map(TypeRefResult::QName);
497
498 let id = attrs
499 .get_value_by_name(name_table, "id")
500 .map(String::from);
501
502 Ok(Self {
503 phase: ExtensionPhase::Annotation,
504 base_type,
505 particle: None,
506 open_content: None,
507 attributes: Vec::new(),
508 attribute_groups: Vec::new(),
509 attribute_wildcard: None,
510 assertions: Vec::new(),
511 id,
512 annotation: None,
513 source,
514 foreign_attributes: Vec::new(),
515 })
516 }
517}
518
519impl Frame for ExtensionFrame {
520 fn allows(&self, local_name: &str, _name_table: &NameTable) -> bool {
521 #[cfg(feature = "xsd11")]
522 let is_xsd11_element = matches!(
523 local_name,
524 xsd_names::OPEN_CONTENT | xsd_names::ASSERT
525 );
526 #[cfg(not(feature = "xsd11"))]
527 let is_xsd11_element = false;
528
529 match self.phase {
530 ExtensionPhase::Annotation => matches!(
531 local_name,
532 xsd_names::ANNOTATION
533 | xsd_names::SEQUENCE
534 | xsd_names::CHOICE
535 | xsd_names::ALL
536 | xsd_names::GROUP
537 | xsd_names::ATTRIBUTE
538 | xsd_names::ATTRIBUTE_GROUP
539 | xsd_names::ANY_ATTRIBUTE
540 ) || is_xsd11_element,
541 ExtensionPhase::Content => matches!(
542 local_name,
543 xsd_names::SEQUENCE
544 | xsd_names::CHOICE
545 | xsd_names::ALL
546 | xsd_names::GROUP
547 | xsd_names::ATTRIBUTE
548 | xsd_names::ATTRIBUTE_GROUP
549 | xsd_names::ANY_ATTRIBUTE
550 ) || is_xsd11_element,
551 ExtensionPhase::Attributes => matches!(
552 local_name,
553 xsd_names::ATTRIBUTE
554 | xsd_names::ATTRIBUTE_GROUP
555 | xsd_names::ANY_ATTRIBUTE
556 ) || is_xsd11_element,
557 ExtensionPhase::Done => false,
558 }
559 }
560
561 fn allows_attribute(&self, local_name: &str, _name_table: &NameTable) -> bool {
562 matches!(local_name, "base" | "id")
563 }
564
565 fn on_child_start(&mut self, local_name: &str, _name_table: &NameTable) {
566 match local_name {
567 xsd_names::ANNOTATION => {
568 self.phase = ExtensionPhase::Content;
569 }
570 xsd_names::SEQUENCE | xsd_names::CHOICE | xsd_names::ALL | xsd_names::GROUP => {
571 self.phase = ExtensionPhase::Attributes;
572 }
573 xsd_names::ATTRIBUTE | xsd_names::ATTRIBUTE_GROUP => {
574 self.phase = ExtensionPhase::Attributes;
575 }
576 xsd_names::ANY_ATTRIBUTE => {
577 self.phase = ExtensionPhase::Done;
578 }
579 _ => {}
580 }
581 }
582
583 fn attach(&mut self, child: FrameResult) -> SchemaResult<()> {
584 match child {
585 FrameResult::Annotation(ann) => {
586 self.annotation = Some(ann);
587 }
588 FrameResult::Particle(particle) => {
589 self.particle = Some(particle);
590 }
591 FrameResult::OpenContent(open_content) => {
592 self.open_content = Some(open_content);
593 }
594 FrameResult::Attribute(attr) => {
595 let use_kind = match attr.use_kind.as_deref() {
596 Some("required") => AttributeUseKind::Required,
597 Some("prohibited") => AttributeUseKind::Prohibited,
598 _ => AttributeUseKind::Optional,
599 };
600 self.attributes.push(AttributeUseResult {
601 attribute: attr,
602 use_kind,
603 });
604 }
605 FrameResult::Group(GroupFrameResult::Attribute(ag)) => {
606 if let Some(ref_name) = ag.ref_name {
607 self.attribute_groups.push(ref_name);
608 }
609 }
610 FrameResult::Group(GroupFrameResult::Model(mg)) => {
611 let min_occurs = mg.min_occurs;
612 let max_occurs = mg.max_occurs;
613 self.particle = Some(ParticleResult {
614 term: ParticleTerm::Group(*mg),
615 min_occurs,
616 max_occurs,
617 source: None,
618 });
619 }
620 FrameResult::Wildcard(wc) => {
621 self.attribute_wildcard = Some(wc);
622 }
623 FrameResult::Assert(assertion) => {
624 self.assertions.push(assertion);
625 }
626 FrameResult::Skip => {}
627 _ => {}
628 }
629 Ok(())
630 }
631
632 fn finish(self: Box<Self>) -> SchemaResult<FrameResult> {
633 let annotation = merge_foreign_attributes(
634 self.annotation,
635 self.foreign_attributes,
636 self.source.clone(),
637 );
638 Ok(FrameResult::Extension(ExtensionResult {
639 base_type: self.base_type,
640 particle: self.particle,
641 open_content: self.open_content,
642 attributes: self.attributes,
643 attribute_groups: self.attribute_groups,
644 attribute_wildcard: self.attribute_wildcard,
645 assertions: self.assertions,
646 id: self.id,
647 annotation,
648 source: self.source,
649 }))
650 }
651
652 fn has_annotation(&self) -> bool {
653 self.annotation.is_some()
654 }
655
656 fn source(&self) -> Option<&SourceRef> {
657 self.source.as_ref()
658 }
659
660 fn set_foreign_attributes(&mut self, attrs: Vec<ForeignAttribute>) {
661 self.foreign_attributes = attrs;
662 }
663}
664
665pub struct ListFrame {
671 item_type: Option<TypeRefResult>,
672 id: Option<String>,
673 annotation: Option<Annotation>,
674 inline_type: Option<SimpleTypeResult>,
675 source: Option<SourceRef>,
676 foreign_attributes: Vec<ForeignAttribute>,
677 saw_inline_type: bool,
684}
685
686impl ListFrame {
687 pub fn new(
688 attrs: &AttributeMap,
689 name_table: &NameTable,
690 source: Option<SourceRef>,
691 ns_snapshot: &NamespaceContextSnapshot,
692 ) -> SchemaResult<Self> {
693 let item_type = attrs
694 .get_value_by_name(name_table, "itemType")
695 .map(|s| parse_qname_ref(s, name_table, ns_snapshot))
696 .transpose()?
697 .map(TypeRefResult::QName);
698
699 let id = attrs
700 .get_value_by_name(name_table, "id")
701 .map(String::from);
702
703 Ok(Self {
704 item_type,
705 id,
706 annotation: None,
707 inline_type: None,
708 source,
709 foreign_attributes: Vec::new(),
710 saw_inline_type: false,
711 })
712 }
713}
714
715impl Frame for ListFrame {
716 fn allows(&self, local_name: &str, _name_table: &NameTable) -> bool {
717 match local_name {
718 xsd_names::ANNOTATION => !self.saw_inline_type,
719 xsd_names::SIMPLE_TYPE => true,
720 _ => false,
721 }
722 }
723
724 fn allows_attribute(&self, local_name: &str, _name_table: &NameTable) -> bool {
725 matches!(local_name, "itemType" | "id")
726 }
727
728 fn on_child_start(&mut self, local_name: &str, _name_table: &NameTable) {
729 if local_name == xsd_names::SIMPLE_TYPE {
730 self.saw_inline_type = true;
731 }
732 }
733
734 fn attach(&mut self, child: FrameResult) -> SchemaResult<()> {
735 match child {
736 FrameResult::Annotation(ann) => {
737 self.annotation = Some(ann);
738 }
739 FrameResult::Type(TypeFrameResult::Simple(st)) => {
740 if self.inline_type.is_some() {
741 return Err(SchemaError::structural(
742 "src-list-itemType-or-simpleType",
743 "xs:list may contain at most one inline <simpleType>",
744 None,
745 ));
746 }
747 self.inline_type = Some(*st);
748 }
749 FrameResult::Skip => {}
750 _ => {}
751 }
752 Ok(())
753 }
754
755 fn finish(self: Box<Self>) -> SchemaResult<FrameResult> {
756 let has_item_type_attr = self.item_type.is_some();
758 let has_inline_type = self.inline_type.is_some();
759
760 if has_item_type_attr && has_inline_type {
761 return Err(SchemaError::structural(
762 "src-list-itemType-or-simpleType",
763 "List cannot have both 'itemType' attribute and inline simpleType",
764 None,
765 ));
766 }
767
768 if !has_item_type_attr && !has_inline_type {
769 return Err(SchemaError::structural(
770 "src-list-itemType-or-simpleType",
771 "List must have either 'itemType' attribute or inline simpleType",
772 None,
773 ));
774 }
775
776 let item = if let Some(inline) = self.inline_type {
777 Some(TypeRefResult::Inline(Box::new(TypeFrameResult::Simple(Box::new(inline)))))
778 } else {
779 self.item_type
780 };
781
782 let annotation = merge_foreign_attributes(
783 self.annotation,
784 self.foreign_attributes,
785 self.source.clone(),
786 );
787 Ok(FrameResult::Type(TypeFrameResult::Simple(Box::new(SimpleTypeResult {
788 name: None,
789 variety: SimpleTypeVariety::List,
790 base_type: None,
791 item_type: item,
792 member_types: Vec::new(),
793 facets: FacetSet::new(),
794 final_derivation: None,
795 id: None,
796 derivation_id: self.id,
797 annotation,
798 source: self.source,
799 }))))
800 }
801
802 fn has_annotation(&self) -> bool {
803 self.annotation.is_some()
804 }
805
806 fn source(&self) -> Option<&SourceRef> {
807 self.source.as_ref()
808 }
809
810 fn set_foreign_attributes(&mut self, attrs: Vec<ForeignAttribute>) {
811 self.foreign_attributes = attrs;
812 }
813}
814
815pub struct UnionFrame {
821 member_types: Vec<TypeRefResult>,
822 id: Option<String>,
823 annotation: Option<Annotation>,
824 source: Option<SourceRef>,
825 foreign_attributes: Vec<ForeignAttribute>,
826 saw_inline_type: bool,
830}
831
832impl UnionFrame {
833 pub fn new(
834 attrs: &AttributeMap,
835 name_table: &NameTable,
836 source: Option<SourceRef>,
837 ns_snapshot: &NamespaceContextSnapshot,
838 ) -> SchemaResult<Self> {
839 let member_types = if let Some(s) = attrs.get_value_by_name(name_table, "memberTypes") {
840 parse_qname_list(s, name_table, ns_snapshot)?
841 .into_iter()
842 .map(TypeRefResult::QName)
843 .collect()
844 } else {
845 Vec::new()
846 };
847
848 let id = attrs
849 .get_value_by_name(name_table, "id")
850 .map(String::from);
851
852 Ok(Self {
853 member_types,
854 id,
855 annotation: None,
856 source,
857 foreign_attributes: Vec::new(),
858 saw_inline_type: false,
859 })
860 }
861}
862
863impl Frame for UnionFrame {
864 fn allows(&self, local_name: &str, _name_table: &NameTable) -> bool {
865 match local_name {
866 xsd_names::ANNOTATION => !self.saw_inline_type,
867 xsd_names::SIMPLE_TYPE => true,
868 _ => false,
869 }
870 }
871
872 fn allows_attribute(&self, local_name: &str, _name_table: &NameTable) -> bool {
873 matches!(local_name, "memberTypes" | "id")
874 }
875
876 fn on_child_start(&mut self, local_name: &str, _name_table: &NameTable) {
877 if local_name == xsd_names::SIMPLE_TYPE {
878 self.saw_inline_type = true;
879 }
880 }
881
882 fn attach(&mut self, child: FrameResult) -> SchemaResult<()> {
883 match child {
884 FrameResult::Annotation(ann) => {
885 self.annotation = Some(ann);
886 }
887 FrameResult::Type(TypeFrameResult::Simple(st)) => {
888 self.member_types.push(TypeRefResult::Inline(Box::new(
889 TypeFrameResult::Simple(st),
890 )));
891 }
892 FrameResult::Skip => {}
893 _ => {}
894 }
895 Ok(())
896 }
897
898 fn finish(self: Box<Self>) -> SchemaResult<FrameResult> {
899 if self.member_types.is_empty() {
901 return Err(SchemaError::structural(
902 "src-union-memberTypes-or-simpleTypes",
903 "Union must have 'memberTypes' attribute or inline simpleType children",
904 None,
905 ));
906 }
907
908 let annotation = merge_foreign_attributes(
909 self.annotation,
910 self.foreign_attributes,
911 self.source.clone(),
912 );
913 Ok(FrameResult::Type(TypeFrameResult::Simple(Box::new(SimpleTypeResult {
914 name: None,
915 variety: SimpleTypeVariety::Union,
916 base_type: None,
917 item_type: None,
918 member_types: self.member_types,
919 facets: FacetSet::new(),
920 final_derivation: None,
921 id: None,
922 derivation_id: self.id,
923 annotation,
924 source: self.source,
925 }))))
926 }
927
928 fn has_annotation(&self) -> bool {
929 self.annotation.is_some()
930 }
931
932 fn source(&self) -> Option<&SourceRef> {
933 self.source.as_ref()
934 }
935
936 fn set_foreign_attributes(&mut self, attrs: Vec<ForeignAttribute>) {
937 self.foreign_attributes = attrs;
938 }
939}
940
941fn reject_simple_content_particle_or_open_content(
951 context: &str,
952 particle: Option<&ParticleResult>,
953 open_content: Option<&OpenContentResult>,
954) -> SchemaResult<()> {
955 if particle.is_some() {
956 return Err(SchemaError::structural(
957 "src-ct",
958 format!(
959 "{context} must not contain a model group \
960 (xs:sequence, xs:choice, xs:all, or xs:group)"
961 ),
962 None,
963 ));
964 }
965 if open_content.is_some() {
966 return Err(SchemaError::structural(
967 "src-ct",
968 format!("{context} must not contain xs:openContent"),
969 None,
970 ));
971 }
972 Ok(())
973}
974
975pub struct SimpleContentFrame {
977 id: Option<String>,
978 base_type: Option<TypeRefResult>,
979 content_type: Option<Box<SimpleTypeResult>>,
980 derivation: Option<DerivationMethod>,
981 facets: FacetSet,
982 attributes: Vec<AttributeUseResult>,
983 attribute_groups: Vec<QNameRef>,
984 attribute_wildcard: Option<WildcardResult>,
985 assertions: Vec<AssertResult>,
986 derivation_id: Option<String>,
987 annotation: Option<Annotation>,
988 source: Option<SourceRef>,
989 foreign_attributes: Vec<ForeignAttribute>,
990 derivation_seen: bool,
995}
996
997impl SimpleContentFrame {
998 pub fn new(
999 attrs: &AttributeMap,
1000 name_table: &NameTable,
1001 source: Option<SourceRef>,
1002 ) -> SchemaResult<Self> {
1003 let id = attrs
1004 .get_value_by_name(name_table, "id")
1005 .map(String::from);
1006
1007 Ok(Self {
1008 id,
1009 base_type: None,
1010 content_type: None,
1011 derivation: None,
1012 facets: FacetSet::new(),
1013 attributes: Vec::new(),
1014 attribute_groups: Vec::new(),
1015 attribute_wildcard: None,
1016 assertions: Vec::new(),
1017 derivation_id: None,
1018 annotation: None,
1019 source,
1020 foreign_attributes: Vec::new(),
1021 derivation_seen: false,
1022 })
1023 }
1024}
1025
1026impl Frame for SimpleContentFrame {
1027 fn allows(&self, local_name: &str, _name_table: &NameTable) -> bool {
1028 if self.derivation_seen {
1029 return false;
1030 }
1031 matches!(
1032 local_name,
1033 xsd_names::ANNOTATION | xsd_names::RESTRICTION | xsd_names::EXTENSION
1034 )
1035 }
1036
1037 fn allows_attribute(&self, local_name: &str, _name_table: &NameTable) -> bool {
1038 matches!(local_name, "id")
1039 }
1040
1041 fn on_child_start(&mut self, local_name: &str, _name_table: &NameTable) {
1042 if matches!(local_name, xsd_names::RESTRICTION | xsd_names::EXTENSION) {
1043 self.derivation_seen = true;
1044 }
1045 }
1046
1047 fn attach(&mut self, child: FrameResult) -> SchemaResult<()> {
1048 match child {
1049 FrameResult::Annotation(ann) => {
1050 self.annotation = Some(ann);
1051 }
1052 FrameResult::Restriction(res) => {
1053 reject_simple_content_particle_or_open_content(
1057 "xs:simpleContent/xs:restriction",
1058 res.particle.as_ref(),
1059 res.open_content.as_ref(),
1060 )?;
1061 if res.base_type.is_some() && res.inline_type.is_some() {
1062 self.base_type = res.base_type.clone();
1066 self.content_type = res.inline_type.map(Box::new);
1067 self.facets = res.facets.clone();
1068 } else {
1069 let base = if let Some(inline) = res.inline_type.clone() {
1070 Some(TypeRefResult::Inline(Box::new(TypeFrameResult::Simple(Box::new(inline)))))
1071 } else {
1072 res.base_type.clone()
1073 };
1074 self.base_type = base;
1075 self.facets = res.facets.clone();
1076 }
1077 self.derivation = Some(DerivationMethod::Restriction);
1078 self.attributes = res.attributes.clone();
1079 self.attribute_groups = res.attribute_groups.clone();
1080 self.attribute_wildcard = res.attribute_wildcard.clone();
1081 self.assertions = res.assertions.clone();
1082 self.derivation_id = res.id.clone();
1083 }
1084 FrameResult::Extension(res) => {
1085 reject_simple_content_particle_or_open_content(
1086 "xs:simpleContent/xs:extension",
1087 res.particle.as_ref(),
1088 res.open_content.as_ref(),
1089 )?;
1090 self.base_type = res.base_type;
1091 self.derivation = Some(DerivationMethod::Extension);
1092 self.attributes = res.attributes;
1093 self.attribute_groups = res.attribute_groups;
1094 self.attribute_wildcard = res.attribute_wildcard;
1095 self.assertions = res.assertions;
1096 self.derivation_id = res.id;
1097 }
1098 FrameResult::Skip => {}
1099 _ => {}
1100 }
1101 Ok(())
1102 }
1103
1104 fn finish(self: Box<Self>) -> SchemaResult<FrameResult> {
1105 let base_type = self.base_type.ok_or_else(|| SchemaError::structural(
1106 "ct-props-correct",
1107 "xs:simpleContent requires a base type",
1108 None,
1109 ))?;
1110
1111 Ok(FrameResult::SimpleContent(SimpleContentDefResult {
1112 base_type: Some(base_type),
1113 content_type: self.content_type,
1114 derivation: self.derivation.unwrap_or(DerivationMethod::Restriction),
1115 facets: self.facets,
1116 attributes: self.attributes,
1117 attribute_groups: self.attribute_groups,
1118 attribute_wildcard: self.attribute_wildcard,
1119 assertions: self.assertions,
1120 id: self.id,
1121 derivation_id: self.derivation_id,
1122 source: self.source,
1123 }))
1124 }
1125
1126 fn has_annotation(&self) -> bool {
1127 self.annotation.is_some()
1128 }
1129
1130 fn source(&self) -> Option<&SourceRef> {
1131 self.source.as_ref()
1132 }
1133
1134 fn set_foreign_attributes(&mut self, attrs: Vec<ForeignAttribute>) {
1135 self.foreign_attributes = attrs;
1136 }
1137}
1138
1139pub struct ComplexContentFrame {
1141 id: Option<String>,
1142 mixed: bool,
1143 mixed_explicit: bool,
1146 base_type: Option<TypeRefResult>,
1147 derivation: Option<DerivationMethod>,
1148 particle: Option<ParticleResult>,
1149 open_content: Option<OpenContentResult>,
1150 attributes: Vec<AttributeUseResult>,
1151 attribute_groups: Vec<QNameRef>,
1152 attribute_wildcard: Option<WildcardResult>,
1153 assertions: Vec<AssertResult>,
1154 derivation_id: Option<String>,
1155 annotation: Option<Annotation>,
1156 source: Option<SourceRef>,
1157 foreign_attributes: Vec<ForeignAttribute>,
1158 derivation_seen: bool,
1160}
1161
1162impl ComplexContentFrame {
1163 pub fn new(
1164 attrs: &AttributeMap,
1165 name_table: &NameTable,
1166 source: Option<SourceRef>,
1167 ) -> SchemaResult<Self> {
1168 let id = attrs
1169 .get_value_by_name(name_table, "id")
1170 .map(String::from);
1171
1172 let mixed_opt = parse_optional_bool_attr(attrs, name_table, "mixed")?;
1173 let mixed_explicit = mixed_opt.is_some();
1174 let mixed = mixed_opt.unwrap_or(false);
1175
1176 Ok(Self {
1177 id,
1178 mixed,
1179 mixed_explicit,
1180 base_type: None,
1181 derivation: None,
1182 particle: None,
1183 open_content: None,
1184 attributes: Vec::new(),
1185 attribute_groups: Vec::new(),
1186 attribute_wildcard: None,
1187 assertions: Vec::new(),
1188 derivation_id: None,
1189 annotation: None,
1190 source,
1191 foreign_attributes: Vec::new(),
1192 derivation_seen: false,
1193 })
1194 }
1195}
1196
1197impl Frame for ComplexContentFrame {
1198 fn allows(&self, local_name: &str, _name_table: &NameTable) -> bool {
1199 if self.derivation_seen {
1200 return false;
1201 }
1202 matches!(
1203 local_name,
1204 xsd_names::ANNOTATION | xsd_names::RESTRICTION | xsd_names::EXTENSION
1205 )
1206 }
1207
1208 fn allows_attribute(&self, local_name: &str, _name_table: &NameTable) -> bool {
1209 matches!(local_name, "id" | "mixed")
1210 }
1211
1212 fn on_child_start(&mut self, local_name: &str, _name_table: &NameTable) {
1213 if matches!(local_name, xsd_names::RESTRICTION | xsd_names::EXTENSION) {
1214 self.derivation_seen = true;
1215 }
1216 }
1217
1218 fn attach(&mut self, child: FrameResult) -> SchemaResult<()> {
1219 match child {
1220 FrameResult::Annotation(ann) => {
1221 self.annotation = Some(ann);
1222 }
1223 FrameResult::Restriction(res) => {
1224 self.base_type = res.base_type.clone();
1225 self.derivation = Some(DerivationMethod::Restriction);
1226 self.particle = res.particle.clone();
1227 self.open_content = res.open_content.clone();
1228 self.attributes = res.attributes.clone();
1229 self.attribute_groups = res.attribute_groups.clone();
1230 self.attribute_wildcard = res.attribute_wildcard.clone();
1231 self.assertions = res.assertions.clone();
1232 self.derivation_id = res.id.clone();
1233 }
1234 FrameResult::Extension(res) => {
1235 self.base_type = res.base_type;
1236 self.derivation = Some(DerivationMethod::Extension);
1237 self.particle = res.particle;
1238 self.open_content = res.open_content;
1239 self.attributes = res.attributes;
1240 self.attribute_groups = res.attribute_groups;
1241 self.attribute_wildcard = res.attribute_wildcard;
1242 self.assertions = res.assertions;
1243 self.derivation_id = res.id;
1244 }
1245 FrameResult::Skip => {}
1246 _ => {}
1247 }
1248 Ok(())
1249 }
1250
1251 fn finish(self: Box<Self>) -> SchemaResult<FrameResult> {
1252 let derivation = self.derivation.ok_or_else(|| SchemaError::structural(
1257 "src-ct",
1258 "xs:complexContent requires an xs:restriction or xs:extension child",
1259 None,
1260 ))?;
1261 Ok(FrameResult::ComplexContent(ComplexContentDefResult {
1262 particle: self.particle,
1263 derivation,
1264 mixed: self.mixed,
1265 mixed_explicit: self.mixed_explicit,
1266 base_type: self.base_type,
1267 open_content: self.open_content,
1268 attributes: self.attributes,
1269 attribute_groups: self.attribute_groups,
1270 attribute_wildcard: self.attribute_wildcard,
1271 assertions: self.assertions,
1272 id: self.id,
1273 derivation_id: self.derivation_id,
1274 source: self.source,
1275 }))
1276 }
1277
1278 fn has_annotation(&self) -> bool {
1279 self.annotation.is_some()
1280 }
1281
1282 fn source(&self) -> Option<&SourceRef> {
1283 self.source.as_ref()
1284 }
1285
1286 fn set_foreign_attributes(&mut self, attrs: Vec<ForeignAttribute>) {
1287 self.foreign_attributes = attrs;
1288 }
1289}
1290
1291#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1297enum ComplexTypePhase {
1298 Annotation,
1299 Content,
1300 Attributes,
1301 Done,
1302}
1303
1304pub struct ComplexTypeFrame {
1306 phase: ComplexTypePhase,
1307 name: Option<NameId>,
1308 base_type: Option<TypeRefResult>,
1309 derivation_method: Option<DerivationMethod>,
1310 mixed: bool,
1311 mixed_explicit: bool,
1315 is_abstract: bool,
1316 final_derivation: Option<DerivationSet>,
1317 block: Option<DerivationSet>,
1318 default_attributes_apply: bool,
1319 id: Option<String>,
1320 content: ComplexContentResult,
1321 open_content: Option<OpenContentResult>,
1322 attributes: Vec<AttributeUseResult>,
1323 attribute_groups: Vec<QNameRef>,
1324 attribute_wildcard: Option<WildcardResult>,
1325 assertions: Vec<AssertResult>,
1326 #[cfg(feature = "xsd11")]
1327 xpath_default_namespace: Option<String>,
1328 annotation: Option<Annotation>,
1329 source: Option<SourceRef>,
1330 foreign_attributes: Vec<ForeignAttribute>,
1331}
1332
1333impl ComplexTypeFrame {
1334 pub fn new(
1335 attrs: &AttributeMap,
1336 name_table: &NameTable,
1337 source: Option<SourceRef>,
1338 ) -> SchemaResult<Self> {
1339 let name = attrs
1340 .get_value_by_name(name_table, "name")
1341 .and_then(|s| name_table.get(s));
1342
1343 let mixed_opt = parse_optional_bool_attr(attrs, name_table, "mixed")?;
1344 let mixed_explicit = mixed_opt.is_some();
1345 let mixed = mixed_opt.unwrap_or(false);
1346
1347 let is_abstract = parse_bool_attr_default(attrs, name_table, "abstract", false)?;
1348
1349 let final_derivation = parse_derivation_set_opt(
1350 attrs.get_value_by_name(name_table, "final"),
1351 )?;
1352
1353 let block = parse_derivation_set_opt(
1354 attrs.get_value_by_name(name_table, "block"),
1355 )?;
1356
1357 let default_attributes_apply =
1358 parse_bool_attr_default(attrs, name_table, "defaultAttributesApply", true)?;
1359
1360 let id = attrs
1361 .get_value_by_name(name_table, "id")
1362 .map(String::from);
1363
1364 #[cfg(feature = "xsd11")]
1365 let xpath_default_namespace = attrs
1366 .get_value_by_name(name_table, "xpathDefaultNamespace")
1367 .map(String::from);
1368
1369 Ok(Self {
1370 phase: ComplexTypePhase::Annotation,
1371 name,
1372 base_type: None,
1373 derivation_method: None,
1374 mixed,
1375 mixed_explicit,
1376 is_abstract,
1377 final_derivation,
1378 block,
1379 default_attributes_apply,
1380 id,
1381 content: ComplexContentResult::Empty,
1382 open_content: None,
1383 attributes: Vec::new(),
1384 attribute_groups: Vec::new(),
1385 attribute_wildcard: None,
1386 assertions: Vec::new(),
1387 #[cfg(feature = "xsd11")]
1388 xpath_default_namespace,
1389 annotation: None,
1390 source,
1391 foreign_attributes: Vec::new(),
1392 })
1393 }
1394}
1395
1396impl Frame for ComplexTypeFrame {
1397 fn allows(&self, local_name: &str, _name_table: &NameTable) -> bool {
1398 #[cfg(feature = "xsd11")]
1399 let is_xsd11_element = matches!(
1400 local_name,
1401 xsd_names::OPEN_CONTENT | xsd_names::ASSERT
1402 );
1403 #[cfg(not(feature = "xsd11"))]
1404 let is_xsd11_element = false;
1405
1406 match self.phase {
1407 ComplexTypePhase::Annotation => matches!(
1408 local_name,
1409 xsd_names::ANNOTATION
1410 | xsd_names::SIMPLE_CONTENT
1411 | xsd_names::COMPLEX_CONTENT
1412 | xsd_names::SEQUENCE
1413 | xsd_names::CHOICE
1414 | xsd_names::ALL
1415 | xsd_names::GROUP
1416 | xsd_names::ATTRIBUTE
1417 | xsd_names::ATTRIBUTE_GROUP
1418 | xsd_names::ANY_ATTRIBUTE
1419 ) || is_xsd11_element,
1420 ComplexTypePhase::Content => matches!(
1421 local_name,
1422 xsd_names::SIMPLE_CONTENT
1423 | xsd_names::COMPLEX_CONTENT
1424 | xsd_names::SEQUENCE
1425 | xsd_names::CHOICE
1426 | xsd_names::ALL
1427 | xsd_names::GROUP
1428 | xsd_names::ATTRIBUTE
1429 | xsd_names::ATTRIBUTE_GROUP
1430 | xsd_names::ANY_ATTRIBUTE
1431 ) || is_xsd11_element,
1432 ComplexTypePhase::Attributes => matches!(
1433 local_name,
1434 xsd_names::ATTRIBUTE
1435 | xsd_names::ATTRIBUTE_GROUP
1436 | xsd_names::ANY_ATTRIBUTE
1437 ) || is_xsd11_element,
1438 ComplexTypePhase::Done => false,
1439 }
1440 }
1441
1442 fn allows_attribute(&self, local_name: &str, _name_table: &NameTable) -> bool {
1443 #[cfg(feature = "xsd11")]
1444 if local_name == "xpathDefaultNamespace" {
1445 return true;
1446 }
1447 matches!(
1448 local_name,
1449 "name"
1450 | "mixed"
1451 | "abstract"
1452 | "final"
1453 | "block"
1454 | "defaultAttributesApply"
1455 | "id"
1456 )
1457 }
1458
1459 fn on_child_start(&mut self, local_name: &str, _name_table: &NameTable) {
1460 match local_name {
1461 xsd_names::ANNOTATION => {
1462 self.phase = ComplexTypePhase::Content;
1463 }
1464 xsd_names::SIMPLE_CONTENT | xsd_names::COMPLEX_CONTENT => {
1465 self.phase = ComplexTypePhase::Done;
1466 }
1467 xsd_names::SEQUENCE | xsd_names::CHOICE | xsd_names::ALL | xsd_names::GROUP => {
1468 self.phase = ComplexTypePhase::Attributes;
1469 }
1470 xsd_names::ATTRIBUTE | xsd_names::ATTRIBUTE_GROUP => {
1471 self.phase = ComplexTypePhase::Attributes;
1472 }
1473 xsd_names::ANY_ATTRIBUTE => {
1474 self.phase = ComplexTypePhase::Done;
1475 }
1476 _ => {}
1477 }
1478 }
1479
1480 fn attach(&mut self, child: FrameResult) -> SchemaResult<()> {
1481 match child {
1482 FrameResult::Annotation(ann) => {
1483 self.annotation = Some(ann);
1484 }
1485 FrameResult::OpenContent(open_content) => {
1486 self.open_content = Some(open_content);
1487 }
1488 FrameResult::SimpleContent(mut sc) => {
1489 self.base_type = sc
1490 .base_type
1491 .as_ref()
1492 .and_then(|bt| match bt {
1493 TypeRefResult::QName(qname) => {
1494 Some(TypeRefResult::QName(qname.clone()))
1495 }
1496 _ => None,
1497 });
1498 self.derivation_method = Some(sc.derivation);
1499 self.attributes = std::mem::take(&mut sc.attributes);
1500 self.attribute_groups = std::mem::take(&mut sc.attribute_groups);
1501 self.attribute_wildcard = sc.attribute_wildcard.take();
1502 self.content = ComplexContentResult::Simple(sc);
1503 }
1504 FrameResult::ComplexContent(mut cc) => {
1505 self.base_type = cc
1506 .base_type
1507 .as_ref()
1508 .and_then(|bt| match bt {
1509 TypeRefResult::QName(qname) => {
1510 Some(TypeRefResult::QName(qname.clone()))
1511 }
1512 _ => None,
1513 });
1514 self.derivation_method = Some(cc.derivation);
1515 self.attributes = std::mem::take(&mut cc.attributes);
1516 self.attribute_groups = std::mem::take(&mut cc.attribute_groups);
1517 self.attribute_wildcard = cc.attribute_wildcard.take();
1518 if cc.mixed_explicit && self.mixed_explicit && cc.mixed != self.mixed {
1523 return Err(SchemaError::structural(
1524 "src-ct",
1525 "<complexType mixed=…> and <complexContent mixed=…> are both \
1526 present but disagree (§3.4.2.3 step 1)",
1527 None,
1528 ));
1529 }
1530 if cc.mixed_explicit {
1531 self.mixed = cc.mixed;
1532 } else {
1533 cc.mixed = self.mixed;
1534 }
1535 self.content = ComplexContentResult::Complex(cc);
1536 }
1537 FrameResult::Particle(particle) => {
1538 self.content = ComplexContentResult::Complex(ComplexContentDefResult {
1539 particle: Some(particle),
1540 derivation: DerivationMethod::Restriction,
1541 mixed: self.mixed,
1542 mixed_explicit: true,
1543 base_type: None,
1544 open_content: None,
1545 attributes: Vec::new(),
1546 attribute_groups: Vec::new(),
1547 attribute_wildcard: None,
1548 assertions: Vec::new(),
1549 id: None,
1550 derivation_id: None,
1551 source: None,
1552 });
1553 }
1554 FrameResult::Attribute(attr) => {
1555 let use_kind = match attr.use_kind.as_deref() {
1556 Some("required") => AttributeUseKind::Required,
1557 Some("prohibited") => AttributeUseKind::Prohibited,
1558 _ => AttributeUseKind::Optional,
1559 };
1560 self.attributes.push(AttributeUseResult {
1561 attribute: attr,
1562 use_kind,
1563 });
1564 }
1565 FrameResult::Group(GroupFrameResult::Model(mg)) => {
1566 let min_occurs = mg.min_occurs;
1567 let max_occurs = mg.max_occurs;
1568 let particle = ParticleResult {
1569 term: ParticleTerm::Group(*mg),
1570 min_occurs,
1571 max_occurs,
1572 source: None,
1573 };
1574 self.content = ComplexContentResult::Complex(ComplexContentDefResult {
1575 particle: Some(particle),
1576 derivation: DerivationMethod::Restriction,
1577 mixed: self.mixed,
1578 mixed_explicit: true,
1579 base_type: None,
1580 open_content: None,
1581 attributes: Vec::new(),
1582 attribute_groups: Vec::new(),
1583 attribute_wildcard: None,
1584 assertions: Vec::new(),
1585 id: None,
1586 derivation_id: None,
1587 source: None,
1588 });
1589 }
1590 FrameResult::Group(GroupFrameResult::Attribute(ag)) => {
1591 if let Some(ref_name) = ag.ref_name {
1592 self.attribute_groups.push(ref_name);
1593 }
1594 }
1595 FrameResult::Wildcard(wc) => {
1596 self.attribute_wildcard = Some(wc);
1597 }
1598 FrameResult::Assert(assertion) => {
1599 self.assertions.push(assertion);
1600 }
1601 FrameResult::Skip => {}
1602 _ => {}
1603 }
1604 Ok(())
1605 }
1606
1607 fn finish(self: Box<Self>) -> SchemaResult<FrameResult> {
1608 let mut content = self.content;
1609 match &mut content {
1610 ComplexContentResult::Empty => {
1611 if self.open_content.is_some() || !self.assertions.is_empty() {
1612 content = ComplexContentResult::Complex(ComplexContentDefResult {
1613 particle: None,
1614 derivation: DerivationMethod::Restriction,
1615 mixed: self.mixed,
1616 mixed_explicit: true,
1617 base_type: None,
1618 open_content: self.open_content,
1619 attributes: Vec::new(),
1620 attribute_groups: Vec::new(),
1621 attribute_wildcard: None,
1622 assertions: self.assertions,
1623 id: None,
1624 derivation_id: None,
1625 source: None,
1626 });
1627 }
1628 }
1629 ComplexContentResult::Complex(cc) => {
1630 if cc.open_content.is_none() {
1631 cc.open_content = self.open_content;
1632 }
1633 if !self.assertions.is_empty() {
1634 cc.assertions.extend(self.assertions);
1635 }
1636 }
1637 ComplexContentResult::Simple(_) => {}
1638 }
1639
1640 let annotation = merge_foreign_attributes(
1641 self.annotation,
1642 self.foreign_attributes,
1643 self.source.clone(),
1644 );
1645 Ok(FrameResult::Type(TypeFrameResult::Complex(Box::new(ComplexTypeResult {
1646 name: self.name,
1647 base_type: self.base_type,
1648 derivation_method: self.derivation_method,
1649 content,
1650 attributes: self.attributes,
1651 attribute_groups: self.attribute_groups,
1652 attribute_wildcard: self.attribute_wildcard,
1653 mixed: self.mixed,
1654 is_abstract: self.is_abstract,
1655 final_derivation: self.final_derivation,
1656 block: self.block,
1657 default_attributes_apply: self.default_attributes_apply,
1658 id: self.id,
1659 #[cfg(feature = "xsd11")]
1660 xpath_default_namespace: self.xpath_default_namespace,
1661 annotation,
1662 source: self.source,
1663 }))))
1664 }
1665
1666 fn has_annotation(&self) -> bool {
1667 self.annotation.is_some()
1668 }
1669
1670 fn source(&self) -> Option<&SourceRef> {
1671 self.source.as_ref()
1672 }
1673
1674 fn set_foreign_attributes(&mut self, attrs: Vec<ForeignAttribute>) {
1675 self.foreign_attributes = attrs;
1676 }
1677
1678 fn children_inside_complex_type(&self) -> bool {
1679 true
1680 }
1681}
1682