1#![allow(clippy::redundant_closure_for_method_calls)]
2
3use std::collections::{hash_map::Entry, HashMap, HashSet};
4use std::ops::Not;
5
6use proc_macro2::{Ident as Ident2, TokenStream};
7use quote::{format_ident, quote};
8
9use crate::config::TypedefMode;
10use crate::models::{
11 data::{
12 ComplexBase, ComplexData, ComplexDataAttribute, ComplexDataContent, ComplexDataElement,
13 ComplexDataEnum, ComplexDataStruct, ConstrainsData, DataTypeVariant, DerivedType,
14 DynamicData, EnumerationData, EnumerationTypeVariant, Occurs, ReferenceData, SimpleData,
15 StructMode, UnionData, UnionTypeVariant,
16 },
17 meta::{
18 ComplexMeta, ElementMeta, ElementMetaVariant, ElementMode, MetaTypeVariant, MetaTypes,
19 WhiteSpace,
20 },
21 schema::{xs::Use, MaxOccurs},
22 Ident,
23};
24
25use super::super::super::{
26 context::{Context, ValueKey},
27 RenderStep, RenderStepType,
28};
29
30#[derive(Debug, Clone, Copy)]
32pub struct QuickXmlDeserializeRenderStep {
33 pub boxed_deserializer: bool,
38}
39
40macro_rules! resolve_build_in {
41 ($ctx:ident, $path:expr) => {
42 $ctx.resolve_build_in($path)
43 };
44}
45
46macro_rules! resolve_ident {
47 ($ctx:ident, $path:expr) => {
48 $ctx.resolve_ident_path($path)
49 };
50}
51
52macro_rules! resolve_quick_xml_ident {
53 ($ctx:ident, $path:expr) => {
54 $ctx.resolve_quick_xml_deserialize_ident_path($path)
55 };
56}
57
58struct DeserializerConfig;
59
60impl ValueKey for DeserializerConfig {
61 type Type = QuickXmlDeserializeRenderStep;
62}
63
64impl RenderStep for QuickXmlDeserializeRenderStep {
65 fn render_step_type(&self) -> RenderStepType {
66 RenderStepType::ExtraImpls
67 }
68
69 fn render_type(&mut self, ctx: &mut Context<'_, '_>) {
70 ctx.set::<DeserializerConfig>(*self);
71
72 match &ctx.data.variant {
73 DataTypeVariant::BuildIn(_) | DataTypeVariant::Custom(_) => (),
74 DataTypeVariant::Union(x) => x.render_deserializer(ctx),
75 DataTypeVariant::Dynamic(x) => x.render_deserializer(ctx),
76 DataTypeVariant::Reference(x) => x.render_deserializer(ctx),
77 DataTypeVariant::Enumeration(x) => x.render_deserializer(ctx),
78 DataTypeVariant::Simple(x) => x.render_deserializer(ctx),
79 DataTypeVariant::Complex(x) => x.render_deserializer(ctx),
80 }
81
82 ctx.unset::<DeserializerConfig>();
83 }
84}
85
86impl UnionData<'_> {
89 pub(crate) fn render_deserializer(&self, ctx: &mut Context<'_, '_>) {
90 let Self {
91 type_ident,
92 variants,
93 ..
94 } = self;
95
96 let validation = self.constrains.render_validation(ctx);
97 let variants = variants
98 .iter()
99 .map(|var| var.render_deserializer_variant(ctx, validation.is_some()));
100
101 let vec = resolve_build_in!(ctx, "::alloc::vec::Vec");
102 let u8_ = resolve_build_in!(ctx, "::core::primitive::u8");
103 let result = resolve_build_in!(ctx, "::core::result::Result");
104
105 let error = resolve_ident!(ctx, "xsd_parser_types::quick_xml::Error");
106 let error_kind = resolve_ident!(ctx, "xsd_parser_types::quick_xml::ErrorKind");
107 let deserialize_bytes =
108 resolve_ident!(ctx, "xsd_parser_types::quick_xml::DeserializeBytes");
109 let deserialize_helper =
110 resolve_ident!(ctx, "xsd_parser_types::quick_xml::DeserializeHelper");
111
112 let code = quote! {
113 impl #deserialize_bytes for #type_ident {
114 fn deserialize_bytes(
115 helper: &mut #deserialize_helper,
116 bytes: &[#u8_],
117 ) -> #result<Self, #error> {
118 let mut errors = #vec::new();
119
120 #validation
121
122 #( #variants )*
123
124 Err(#error::from(#error_kind::InvalidUnion(errors.into())))
125 }
126 }
127 };
128
129 ctx.current_module().append(code);
130 }
131}
132
133impl UnionTypeVariant<'_> {
134 fn render_deserializer_variant(&self, ctx: &Context<'_, '_>, as_str: bool) -> TokenStream {
135 let Self {
136 variant_ident,
137 target_type,
138 ..
139 } = self;
140
141 let target_type = ctx.resolve_type_for_module(target_type);
142
143 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
144
145 if as_str {
146 quote! {
147 match #target_type::deserialize_str(helper, s) {
148 Ok(value) => return Ok(Self::#variant_ident(value)),
149 Err(error) => errors.push(#box_::new(error)),
150 }
151 }
152 } else {
153 quote! {
154 match #target_type::deserialize_bytes(helper, bytes) {
155 Ok(value) => return Ok(Self::#variant_ident(value)),
156 Err(error) => errors.push(#box_::new(error)),
157 }
158 }
159 }
160 }
161}
162
163impl DynamicData<'_> {
166 pub(crate) fn render_deserializer(&self, ctx: &mut Context<'_, '_>) {
167 self.render_with_deserializer(ctx);
168 self.render_deserializer_types(ctx);
169 self.render_deserializer_impls(ctx);
170 }
171
172 fn render_with_deserializer(&self, ctx: &mut Context<'_, '_>) {
173 let Self {
174 type_ident,
175 deserializer_ident,
176 ..
177 } = self;
178
179 let config = ctx.get_ref::<DeserializerConfig>();
180 let deserializer_type = if config.boxed_deserializer {
181 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
182
183 quote!(#box_<quick_xml_deserialize::#deserializer_ident>)
184 } else {
185 quote!(quick_xml_deserialize::#deserializer_ident)
186 };
187
188 let with_deserializer =
189 resolve_ident!(ctx, "::xsd_parser_types::quick_xml::WithDeserializer");
190
191 let code = quote! {
192 impl #with_deserializer for #type_ident {
193 type Deserializer = #deserializer_type;
194 }
195 };
196
197 ctx.current_module().append(code);
198 }
199
200 fn render_deserializer_types(&self, ctx: &mut Context<'_, '_>) {
201 let Self {
202 derived_types,
203 deserializer_ident,
204 ..
205 } = self;
206
207 let variants = derived_types.iter().map(|x| {
208 let target_type = ctx.resolve_type_for_deserialize_module(&x.target_type);
209 let variant_ident = &x.variant_ident;
210
211 let with_deserializer =
212 resolve_ident!(ctx, "::xsd_parser_types::quick_xml::WithDeserializer");
213
214 quote! {
215 #variant_ident(<#target_type as #with_deserializer>::Deserializer),
216 }
217 });
218
219 let code = quote! {
220 #[derive(Debug)]
221 pub enum #deserializer_ident {
222 #( #variants )*
223 }
224 };
225
226 ctx.quick_xml_deserialize().append(code);
227 }
228
229 fn render_deserializer_impls(&self, ctx: &mut Context<'_, '_>) {
230 let Self {
231 type_ident,
232 derived_types,
233 deserializer_ident,
234 ..
235 } = self;
236
237 let result = resolve_build_in!(ctx, "::core::result::Result");
238
239 let event = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Event");
240 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
241 let deserializer =
242 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Deserializer");
243 let deserialize_helper =
244 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
245 let deserializer_event =
246 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerEvent");
247 let deserializer_result =
248 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerResult");
249 let deserializer_output =
250 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerOutput");
251 let deserializer_artifact =
252 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerArtifact");
253
254 let config = ctx.get_ref::<DeserializerConfig>();
255 let deserializer_type = if config.boxed_deserializer {
256 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
257
258 quote!(#box_<#deserializer_ident>)
259 } else {
260 quote!(#deserializer_ident)
261 };
262 let boxed_deserializer_ident =
263 boxed_deserializer_ident(config.boxed_deserializer, deserializer_ident);
264 let deref_self = config.boxed_deserializer.then(|| quote!(*));
265
266 let variants_init = derived_types
267 .iter()
268 .map(|x| x.render_deserializer_init(ctx, type_ident, deserializer_ident));
269 let variants_next = derived_types
270 .iter()
271 .map(|x| x.render_deserializer_next(ctx, type_ident, deserializer_ident));
272 let variants_finish = derived_types.iter().map(|x| {
273 let variant_ident = &x.variant_ident;
274
275 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
276 ctx.add_quick_xml_deserialize_usings(true, ["::xsd_parser_types::quick_xml::Deserializer"]);
277
278 quote! {
279 #boxed_deserializer_ident::#variant_ident(x) => Ok(super::#type_ident(#box_::new(x.finish(helper)?))),
280 }
281 });
282
283 let code = quote! {
284 impl<'de> #deserializer<'de, super::#type_ident> for #deserializer_type {
285 fn init(
286 helper: &mut #deserialize_helper,
287 event: #event<'de>,
288 ) -> #deserializer_result<'de, super::#type_ident> {
289 let Some(type_name) = helper.get_dynamic_type_name(&event)? else {
290 return Ok(#deserializer_output {
291 artifact: #deserializer_artifact::None,
292 event: #deserializer_event::None,
293 allow_any: false,
294 });
295 };
296 let type_name = type_name.into_owned();
297
298 #( #variants_init )*
299
300 Ok(#deserializer_output {
301 artifact: #deserializer_artifact::None,
302 event: #deserializer_event::Break(event),
303 allow_any: false,
304 })
305 }
306
307 fn next(
308 self,
309 helper: &mut #deserialize_helper,
310 event: #event<'de>
311 ) -> #deserializer_result<'de, super::#type_ident> {
312 match #deref_self self {
313 #( #variants_next )*
314 }
315 }
316
317 fn finish(
318 self,
319 helper: &mut #deserialize_helper
320 ) -> #result<super::#type_ident, #error> {
321 match #deref_self self {
322 #( #variants_finish )*
323 }
324 }
325 }
326 };
327
328 ctx.quick_xml_deserialize().append(code);
329 }
330}
331
332impl DerivedType {
333 fn render_deserializer_init(
334 &self,
335 ctx: &Context<'_, '_>,
336 type_ident: &Ident2,
337 deserializer_ident: &Ident2,
338 ) -> TokenStream {
339 let Self {
340 ident,
341 b_name,
342 target_type,
343 variant_ident,
344 ..
345 } = self;
346
347 let config = ctx.get_ref::<DeserializerConfig>();
348 let boxed_deserializer_ident =
349 boxed_deserializer_ident(config.boxed_deserializer, deserializer_ident);
350 let deserialize_mapper = ctx.do_box(
351 config.boxed_deserializer,
352 quote!(#boxed_deserializer_ident::#variant_ident(x)),
353 );
354 let target_type = ctx.resolve_type_for_deserialize_module(target_type);
355
356 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
357
358 let qname = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::QName");
359 let with_deserializer =
360 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::WithDeserializer");
361 let deserializer_output =
362 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerOutput");
363
364 ctx.add_quick_xml_deserialize_usings(true, ["::xsd_parser_types::quick_xml::Deserializer"]);
365
366 let body = quote! {
367 let #deserializer_output {
368 artifact,
369 event,
370 allow_any,
371 } = <#target_type as #with_deserializer>::init(helper, event)?;
372
373 return Ok(#deserializer_output {
374 artifact: artifact.map(
375 |x| super::#type_ident(#box_::new(x)),
376 |x| #deserialize_mapper,
377 ),
378 event,
379 allow_any,
380 });
381 };
382
383 if let Some(module) = ident
384 .ns
385 .and_then(|ns| ctx.types.meta.types.modules.get(&ns))
386 {
387 let ns_name = ctx.resolve_type_for_deserialize_module(&module.make_ns_const());
388
389 quote! {
390 if matches!(helper.resolve_local_name(#qname(&type_name), &#ns_name), Some(#b_name)) {
391 #body
392 }
393 }
394 } else {
395 quote! {
396 if type_name == #b_name {
397 #body
398 }
399 }
400 }
401 }
402
403 fn render_deserializer_next(
404 &self,
405 ctx: &Context<'_, '_>,
406 type_ident: &Ident2,
407 deserializer_ident: &Ident2,
408 ) -> TokenStream {
409 let Self { variant_ident, .. } = self;
410
411 let config = ctx.get_ref::<DeserializerConfig>();
412 let boxed_deserializer_ident =
413 boxed_deserializer_ident(config.boxed_deserializer, deserializer_ident);
414 let deserialize_mapper = ctx.do_box(
415 config.boxed_deserializer,
416 quote!(#boxed_deserializer_ident::#variant_ident(x)),
417 );
418
419 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
420
421 let deserializer_output =
422 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerOutput");
423
424 quote! {
425 #boxed_deserializer_ident::#variant_ident(x) => {
426 let #deserializer_output {
427 artifact,
428 event,
429 allow_any,
430 } = x.next(helper, event)?;
431
432 Ok(#deserializer_output {
433 artifact: artifact.map(
434 |x| super::#type_ident(#box_::new(x)),
435 |x| #deserialize_mapper,
436 ),
437 event,
438 allow_any,
439 })
440 },
441 }
442 }
443}
444
445impl ReferenceData<'_> {
448 pub(crate) fn render_deserializer(&self, ctx: &mut Context<'_, '_>) {
449 let Self {
450 mode,
451 occurs,
452 type_ident,
453 target_type,
454 ..
455 } = self;
456
457 if matches!(mode, TypedefMode::Auto | TypedefMode::Typedef) {
458 return;
459 }
460
461 let target_type = ctx.resolve_type_for_module(target_type);
462
463 let vec = resolve_build_in!(ctx, "::alloc::vec::Vec");
464 let result = resolve_build_in!(ctx, "::core::result::Result");
465
466 let body = match occurs {
467 Occurs::None => return,
468 Occurs::Single => {
469 quote! {
470 Ok(Self(#target_type::deserialize_bytes(helper, bytes)?))
471 }
472 }
473 Occurs::Optional => {
474 quote! {
475 Ok(Self(Some(#target_type::deserialize_bytes(helper, bytes)?)))
476 }
477 }
478 Occurs::DynamicList => {
479 quote! {
480 Ok(Self(bytes
481 .split(|b| *b == b' ' || *b == b'|' || *b == b',' || *b == b';')
482 .map(|bytes| #target_type::deserialize_bytes(helper, bytes))
483 .collect::<#result<#vec<_>, _>>()?
484 ))
485 }
486 }
487 Occurs::StaticList(size) => {
488 let option = resolve_build_in!(ctx, "::core::option::Option");
489
490 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
491 let error_kind =
492 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ErrorKind");
493
494 quote! {
495 let arr: [#option<#target_type>; #size];
496 let parts = bytes
497 .split(|b| *b == b' ' || *b == b'|' || *b == b',' || *b == b';')
498 .map(|bytes| #target_type::deserialize_bytes(helper, bytes));
499 let mut index = 0;
500
501 for part in parts {
502 if index >= #size {
503 return Err(#error::from(#error_kind::InsufficientSize {
504 min: #size,
505 max: Some(#size),
506 actual: index,
507 }));
508 }
509
510 arr[index] = Some(part?);
511
512 index += 1;
513 }
514
515 if index < #size {
516 return Err(#error::from(#error_kind::InsufficientSize {
517 min: #size,
518 max: Some(#size),
519 actual: index,
520 }));
521 }
522
523 Ok(Self(arr.map(|x| x.unwrap())))
524 }
525 }
526 };
527
528 let u8_ = resolve_build_in!(ctx, "::core::primitive::u8");
529
530 let error = resolve_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
531 let deserialize_bytes =
532 resolve_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeBytes");
533 let deserialize_helper =
534 resolve_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
535
536 let code = quote! {
537 impl #deserialize_bytes for #type_ident {
538 fn deserialize_bytes(
539 helper: &mut #deserialize_helper,
540 bytes: &[#u8_],
541 ) -> #result<Self, #error> {
542 #body
543 }
544 }
545 };
546
547 ctx.current_module().append(code);
548 }
549}
550
551impl EnumerationData<'_> {
554 pub(crate) fn render_deserializer(&self, ctx: &mut Context<'_, '_>) {
555 let Self {
556 type_ident,
557 variants,
558 ..
559 } = self;
560
561 let mut other = None;
562 let validation = self.constrains.render_validation(ctx);
563 let variants = variants
564 .iter()
565 .filter_map(|v| v.render_deserializer_variant(ctx, &mut other))
566 .collect::<Vec<_>>();
567
568 let u8_ = resolve_build_in!(ctx, "::core::primitive::u8");
569 let result = resolve_build_in!(ctx, "::core::result::Result");
570
571 let error = resolve_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
572 let error_kind = resolve_ident!(ctx, "::xsd_parser_types::quick_xml::ErrorKind");
573 let raw_byte_str = resolve_ident!(ctx, "::xsd_parser_types::quick_xml::RawByteStr");
574 let deserialize_bytes =
575 resolve_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeBytes");
576 let deserialize_helper =
577 resolve_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
578
579 let other = other.unwrap_or_else(|| {
580 quote! {
581 x => Err(
582 #error::from(
583 #error_kind::UnknownOrInvalidValue(
584 #raw_byte_str::from_slice(x)
585 )
586 )
587 ),
588 }
589 });
590
591 let code = quote! {
592 impl #deserialize_bytes for #type_ident {
593 fn deserialize_bytes(
594 helper: &mut #deserialize_helper,
595 bytes: &[#u8_],
596 ) -> #result<Self, #error> {
597 #validation
598
599 match bytes {
600 #( #variants )*
601 #other
602 }
603 }
604 }
605 };
606
607 ctx.current_module().append(code);
608 }
609}
610
611impl EnumerationTypeVariant<'_> {
612 fn render_deserializer_variant(
613 &self,
614 ctx: &Context<'_, '_>,
615 other: &mut Option<TokenStream>,
616 ) -> Option<TokenStream> {
617 let Self {
618 b_name,
619 target_type,
620 variant_ident,
621 ..
622 } = self;
623
624 if let Some(target_type) = target_type {
625 let target_type = ctx.resolve_type_for_module(target_type);
626
627 *other = Some(
628 quote! { x => Ok(Self::#variant_ident(#target_type::deserialize_bytes(helper, x)?)), },
629 );
630
631 return None;
632 }
633
634 Some(quote! {
635 #b_name => Ok(Self::#variant_ident),
636 })
637 }
638}
639
640impl SimpleData<'_> {
641 pub(crate) fn render_deserializer(&self, ctx: &mut Context<'_, '_>) {
642 let Self {
643 occurs,
644 type_ident,
645 target_type,
646 ..
647 } = self;
648
649 let target_type = ctx.resolve_type_for_module(target_type);
650
651 let vec = resolve_build_in!(ctx, "::alloc::vec::Vec");
652 let u8_ = resolve_build_in!(ctx, "::core::primitive::u8");
653 let result = resolve_build_in!(ctx, "::core::result::Result");
654
655 let error = resolve_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
656 let deserialize_bytes =
657 resolve_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeBytes");
658 let deserialize_helper =
659 resolve_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
660
661 let validation = self.constrains.render_validation(ctx);
662
663 let body = match (validation.is_some(), occurs) {
664 (true, Occurs::Single) => {
665 quote! {
666 let inner = #target_type::deserialize_str(helper, s)?;
667 }
668 }
669 (false, Occurs::Single) => {
670 quote! {
671 let inner = #target_type::deserialize_bytes(helper, bytes)?;
672 }
673 }
674 (false, Occurs::DynamicList) => {
675 quote! {
676 let inner = bytes
677 .split(|b| *b == b' ' || *b == b'|' || *b == b',' || *b == b';')
678 .map(|bytes| #target_type::deserialize_bytes(helper, bytes))
679 .collect::<#result<#vec<_>, _>>()?;
680 }
681 }
682 (need_str, occurs) => {
683 unreachable!("Invalid (`need_str`, `occurs`) combination: ({need_str}, {occurs:?})")
684 }
685 };
686
687 let code = quote! {
688 impl #deserialize_bytes for #type_ident {
689 fn deserialize_bytes(
690 helper: &mut #deserialize_helper,
691 bytes: &[#u8_],
692 ) -> #result<Self, #error> {
693 #validation
694
695 #body
696
697 Ok(Self::new(inner).map_err(|error| (bytes, error))?)
698 }
699 }
700 };
701
702 ctx.current_module().append(code);
703 }
704}
705
706impl ConstrainsData<'_> {
709 fn render_validation(&self, ctx: &Context<'_, '_>) -> Option<TokenStream> {
710 let whitespace = self.render_whitespace(ctx);
711 let validate_str = self.render_validate_str();
712
713 if whitespace.is_some() || validate_str.is_some() {
714 let error = resolve_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
715 let from_utf8 = resolve_ident!(ctx, "::core::str::from_utf8");
716
717 Some(quote! {
718 let s = #from_utf8(bytes).map_err(#error::from)?;
719
720 #whitespace
721 #validate_str
722 })
723 } else {
724 None
725 }
726 }
727
728 fn render_whitespace(&self, ctx: &Context<'_, '_>) -> Option<TokenStream> {
729 match &self.meta.whitespace {
730 WhiteSpace::Preserve => None,
731 WhiteSpace::Replace => {
732 let whitespace_replace =
733 resolve_ident!(ctx, "::xsd_parser_types::quick_xml::whitespace_replace");
734
735 Some(quote! {
736 let buffer = #whitespace_replace(s);
737 let s = buffer.as_str();
738 })
739 }
740 WhiteSpace::Collapse => {
741 let whitespace_collapse =
742 resolve_ident!(ctx, "::xsd_parser_types::quick_xml::whitespace_collapse");
743
744 Some(quote! {
745 let buffer = #whitespace_collapse(s);
746 let s = buffer.trim();
747 })
748 }
749 }
750 }
751
752 fn render_validate_str(&self) -> Option<TokenStream> {
753 self.meta.need_string_validation().then(|| {
754 quote! {
755 Self::validate_str(s).map_err(|error| (bytes, error))?;
756 }
757 })
758 }
759}
760
761impl ComplexData<'_> {
764 pub(crate) fn render_deserializer(&self, ctx: &mut Context<'_, '_>) {
765 match self {
766 Self::Enum {
767 type_,
768 content_type,
769 } => {
770 type_.render_deserializer(ctx);
771
772 if let Some(content_type) = content_type {
773 ctx.set_content(true);
774 content_type.render_deserializer(ctx);
775 ctx.set_content(false);
776 }
777 }
778 Self::Struct {
779 type_,
780 content_type,
781 } => {
782 type_.render_deserializer(ctx);
783
784 if let Some(content_type) = content_type {
785 ctx.set_content(true);
786 content_type.render_deserializer(ctx);
787 ctx.set_content(false);
788 }
789 }
790 }
791 }
792}
793
794impl ComplexBase<'_> {
795 fn return_end_event(&self, ctx: &Context<'_, '_>) -> (TokenStream, TokenStream) {
796 let deserializer_event =
797 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerEvent");
798
799 if self.represents_element() {
800 (quote!(), quote!(#deserializer_event::None))
801 } else {
802 (
803 quote!(event @),
804 quote!(#deserializer_event::Continue(event)),
805 )
806 }
807 }
808
809 fn render_with_deserializer(&self, ctx: &mut Context<'_, '_>) {
810 let Self {
811 type_ident,
812 deserializer_ident,
813 ..
814 } = self;
815
816 let config = ctx.get_ref::<DeserializerConfig>();
817 let deserializer_type = if config.boxed_deserializer {
818 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
819
820 quote!(#box_<quick_xml_deserialize::#deserializer_ident>)
821 } else {
822 quote!(quick_xml_deserialize::#deserializer_ident)
823 };
824
825 let with_deserializer =
826 resolve_ident!(ctx, "::xsd_parser_types::quick_xml::WithDeserializer");
827
828 let code = quote! {
829 impl #with_deserializer for #type_ident {
830 type Deserializer = #deserializer_type;
831 }
832 };
833
834 ctx.current_module().append(code);
835 }
836
837 fn render_deserializer_impl(
838 &self,
839 ctx: &mut Context<'_, '_>,
840 fn_init: &TokenStream,
841 fn_next: &TokenStream,
842 fn_finish: &TokenStream,
843 finish_mut_self: bool,
844 ) {
845 let type_ident = &self.type_ident;
846 let deserializer_ident = &self.deserializer_ident;
847 let config = ctx.get_ref::<DeserializerConfig>();
848 let deserializer_type = if config.boxed_deserializer {
849 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
850
851 quote!(#box_<#deserializer_ident>)
852 } else {
853 quote!(#deserializer_ident)
854 };
855 let mut_ = finish_mut_self.then(|| quote!(mut));
856
857 let result = resolve_build_in!(ctx, "::core::result::Result");
858
859 let event = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Event");
860 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
861 let deserializer =
862 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Deserializer");
863 let deserialize_helper =
864 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
865 let deserializer_result =
866 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerResult");
867
868 let code = quote! {
869 impl<'de> #deserializer<'de, super::#type_ident> for #deserializer_type {
870 fn init(
871 helper: &mut #deserialize_helper,
872 event: #event<'de>,
873 ) -> #deserializer_result<'de, super::#type_ident> {
874 #fn_init
875 }
876
877 fn next(
878 mut self,
879 helper: &mut #deserialize_helper,
880 event: #event<'de>,
881 ) -> #deserializer_result<'de, super::#type_ident> {
882 #fn_next
883 }
884
885 fn finish(#mut_ self, helper: &mut #deserialize_helper) -> #result<super::#type_ident, #error> {
886 #fn_finish
887 }
888 }
889 };
890
891 ctx.quick_xml_deserialize().append(code);
892 }
893
894 fn render_deserializer_fn_init_for_element(&self, ctx: &Context<'_, '_>) -> TokenStream {
895 let _ctx = ctx;
896 let deserializer_ident = &self.deserializer_ident;
897 let config = ctx.get_ref::<DeserializerConfig>();
898 let boxed_deserializer_ident =
899 boxed_deserializer_ident(config.boxed_deserializer, deserializer_ident);
900
901 quote! {
902 helper.init_deserializer_from_start_event(event, #boxed_deserializer_ident::from_bytes_start)
903 }
904 }
905}
906
907impl ComplexDataEnum<'_> {
908 fn render_deserializer(&self, ctx: &mut Context<'_, '_>) {
909 self.render_with_deserializer(ctx);
910 self.render_deserializer_type(ctx);
911 self.render_deserializer_state_type(ctx);
912 self.render_deserializer_helper(ctx);
913 self.render_deserializer_impl(ctx);
914 }
915
916 fn render_deserializer_type(&self, ctx: &mut Context<'_, '_>) {
917 let deserializer_ident = &self.deserializer_ident;
918 let deserializer_state_ident = &self.deserializer_state_ident;
919
920 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
921
922 let code = quote! {
923 #[derive(Debug)]
924 pub struct #deserializer_ident {
925 state__: #box_<#deserializer_state_ident>,
926 }
927 };
928
929 ctx.quick_xml_deserialize().append(code);
930 }
931
932 fn render_deserializer_state_type(&self, ctx: &mut Context<'_, '_>) {
933 let type_ident = &self.type_ident;
934 let deserializer_state_ident = &self.deserializer_state_ident;
935 let variants = self
936 .elements
937 .iter()
938 .map(|x| x.deserializer_enum_variant_decl(ctx));
939
940 let code = quote! {
941 #[derive(Debug)]
942 pub enum #deserializer_state_ident {
943 Init__,
944 #( #variants )*
945 Done__(super::#type_ident),
946 Unknown__,
947 }
948 };
949
950 ctx.quick_xml_deserialize().append(code);
951 }
952
953 fn render_deserializer_helper(&self, ctx: &mut Context<'_, '_>) {
954 let config = ctx.get::<DeserializerConfig>();
955 let is_defaultable = ctx.is_defaultable_type();
956
957 let represents_element = self.represents_element();
958 let deserializer_ident = &self.deserializer_ident;
959 let deserializer_state_ident = &self.deserializer_state_ident;
960
961 let fn_find_suitable = self.render_deserializer_fn_find_suitable(ctx);
962 let fn_from_bytes_start =
963 represents_element.then(|| self.render_deserializer_fn_from_bytes_start(ctx));
964 let fn_finish_state = self.render_deserializer_fn_finish_state(ctx);
965
966 let store_elements = self
967 .elements
968 .iter()
969 .map(|x| x.deserializer_enum_variant_fn_store(ctx))
970 .collect::<Vec<_>>();
971 let handle_elements = self
972 .elements
973 .iter()
974 .map(|x| {
975 x.deserializer_enum_variant_fn_handle(
976 ctx,
977 represents_element,
978 &boxed_deserializer_ident(config.boxed_deserializer, deserializer_ident),
979 deserializer_state_ident,
980 )
981 })
982 .collect::<Vec<_>>();
983
984 let impl_default = is_defaultable.then(|| self.render_deserializer_impl_default(ctx));
985
986 let code = quote! {
987 impl #deserializer_ident {
988 #fn_find_suitable
989 #fn_from_bytes_start
990 #fn_finish_state
991
992 #( #store_elements )*
993 #( #handle_elements )*
994 }
995
996 #impl_default
997 };
998
999 ctx.quick_xml_deserialize().append(code);
1000 }
1001
1002 fn render_deserializer_fn_find_suitable(&self, ctx: &Context<'_, '_>) -> TokenStream {
1003 let allow_any = self.allow_any;
1004 let deserializer_state_ident = &self.deserializer_state_ident;
1005
1006 let result = resolve_build_in!(ctx, "::core::result::Result");
1007
1008 let event = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Event");
1009 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
1010 let deserialize_helper =
1011 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
1012 let element_handler_output =
1013 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ElementHandlerOutput");
1014
1015 let text = self
1016 .elements
1017 .iter()
1018 .find_map(|x| x.deserializer_enum_variant_init_text(ctx));
1019 let elements = self
1020 .elements
1021 .iter()
1022 .filter_map(|x| x.deserializer_enum_variant_init_element(ctx))
1023 .collect::<Vec<_>>();
1024 let groups = self
1025 .elements
1026 .iter()
1027 .filter_map(|x| x.deserializer_enum_variant_init_group(ctx, !allow_any))
1028 .collect::<Vec<_>>();
1029 let any = self
1030 .elements
1031 .iter()
1032 .filter_map(|x| x.deserializer_enum_variant_init_any(ctx))
1033 .collect::<Vec<_>>();
1034
1035 let x = if elements.is_empty() {
1036 quote!(_)
1037 } else {
1038 quote!(x)
1039 };
1040
1041 let event_decl = (!groups.is_empty() || !any.is_empty() || text.is_some())
1042 .then(|| quote!(let mut event = event;));
1043 let (allow_any_result, allow_any_decl) = if groups.is_empty() || allow_any {
1044 (quote!(#allow_any), None)
1045 } else {
1046 (
1047 quote!(allow_any_element),
1048 Some(quote!(let mut allow_any_element = false;)),
1049 )
1050 };
1051
1052 quote! {
1053 fn find_suitable<'de>(
1054 &mut self,
1055 helper: &mut #deserialize_helper,
1056 event: #event<'de>,
1057 ) -> #result<#element_handler_output<'de>, #error> {
1058 #event_decl
1059 #allow_any_decl
1060
1061 if let #event::Start(#x) | #event::Empty(#x) = &event {
1062 #( #elements )*
1063 #( #groups )*
1064 #( #any )*
1065 }
1066
1067 #text
1068
1069 *self.state__ = #deserializer_state_ident::Init__;
1070
1071 Ok(#element_handler_output::return_to_parent(event, #allow_any_result))
1072 }
1073 }
1074 }
1075
1076 fn render_deserializer_fn_from_bytes_start(&self, ctx: &mut Context<'_, '_>) -> TokenStream {
1077 let config = ctx.get::<DeserializerConfig>();
1078 let is_defaultable = ctx.is_defaultable_type();
1079
1080 let deserializer_state_ident = &self.deserializer_state_ident;
1081
1082 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
1083 let result = resolve_build_in!(ctx, "::core::result::Result");
1084
1085 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
1086 let bytes_start =
1087 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::BytesStart");
1088 let deserialize_helper =
1089 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
1090
1091 let self_type = if config.boxed_deserializer {
1092 quote!(#box_<Self>)
1093 } else {
1094 quote!(Self)
1095 };
1096
1097 let self_ctor = if is_defaultable {
1098 quote!(Self::default())
1099 } else {
1100 quote! {
1101 Self {
1102 state__: #box_::new(#deserializer_state_ident::Init__)
1103 }
1104 }
1105 };
1106 let self_ctor = ctx.do_box(config.boxed_deserializer, self_ctor);
1107
1108 let attrib_loop = self.allow_any_attribute.not().then(|| {
1109 quote! {
1110 for attrib in helper.filter_xmlns_attributes(bytes_start) {
1111 let attrib = attrib?;
1112 helper.raise_unexpected_attrib_checked(&attrib)?;
1113 }
1114 }
1115 });
1116
1117 quote! {
1118 fn from_bytes_start(
1119 helper: &mut #deserialize_helper,
1120 bytes_start: &#bytes_start<'_>
1121 ) -> #result<#self_type, #error> {
1122 #attrib_loop
1123
1124 Ok(#self_ctor)
1125 }
1126 }
1127 }
1128
1129 fn render_deserializer_fn_finish_state(&self, ctx: &mut Context<'_, '_>) -> TokenStream {
1130 let config = ctx.get::<DeserializerConfig>();
1131 let is_defaultable = ctx.is_defaultable_type();
1132
1133 let type_ident = &self.type_ident;
1134 let deserializer_ident = &self.deserializer_ident;
1135 let deserializer_state_ident = &self.deserializer_state_ident;
1136
1137 let result = resolve_build_in!(ctx, "::core::result::Result");
1138
1139 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
1140 let error_kind = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ErrorKind");
1141 let deserialize_helper =
1142 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
1143
1144 let finish_elements = self
1145 .elements
1146 .iter()
1147 .map(|x| {
1148 x.deserializer_enum_variant_finish(
1149 ctx,
1150 type_ident,
1151 &boxed_deserializer_ident(config.boxed_deserializer, deserializer_ident),
1152 )
1153 })
1154 .collect::<Vec<_>>();
1155
1156 let finish_init = if is_defaultable {
1157 self.elements[0].deserializer_enum_variant_default(ctx, type_ident)
1158 } else {
1159 quote!(Err(#error_kind::MissingContent.into()))
1160 };
1161
1162 quote! {
1163 fn finish_state(helper: &mut #deserialize_helper, state: #deserializer_state_ident) -> #result<super::#type_ident, #error> {
1164 use #deserializer_state_ident as S;
1165
1166 match state {
1167 S::Init__ => #finish_init,
1168 #( #finish_elements )*
1169 S::Done__(data) => Ok(data),
1170 _ => unreachable!(),
1171 }
1172 }
1173 }
1174 }
1175
1176 fn render_deserializer_impl_default(&self, ctx: &Context<'_, '_>) -> TokenStream {
1177 let deserializer_ident = &self.deserializer_ident;
1178 let deserializer_state_ident = &self.deserializer_state_ident;
1179
1180 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
1181 let default = resolve_build_in!(ctx, "::core::default::Default");
1182
1183 quote! {
1184 impl #default for #deserializer_ident {
1185 fn default() -> Self {
1186 Self {
1187 state__: #box_::new(#deserializer_state_ident::Init__),
1188 }
1189 }
1190 }
1191 }
1192 }
1193
1194 fn render_deserializer_impl(&self, ctx: &mut Context<'_, '_>) {
1195 let fn_init = self.render_deserializer_fn_init(ctx);
1196 let fn_next = self.render_deserializer_fn_next(ctx);
1197 let fn_finish = self.render_deserializer_fn_finish(ctx);
1198
1199 self.base
1200 .render_deserializer_impl(ctx, &fn_init, &fn_next, &fn_finish, false);
1201 }
1202
1203 fn render_deserializer_fn_init(&self, ctx: &mut Context<'_, '_>) -> TokenStream {
1204 if self.represents_element() {
1205 self.render_deserializer_fn_init_for_element(ctx)
1206 } else {
1207 self.render_deserializer_fn_init_for_group(ctx)
1208 }
1209 }
1210
1211 fn render_deserializer_fn_init_for_group(&self, ctx: &mut Context<'_, '_>) -> TokenStream {
1212 let config = ctx.get::<DeserializerConfig>();
1213 let is_defaultable = ctx.is_defaultable_type();
1214
1215 let deserializer_ident = &self.deserializer_ident;
1216 let deserializer_state_ident = &self.deserializer_state_ident;
1217
1218 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
1219
1220 let deserializer_artifact =
1221 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerArtifact");
1222
1223 let boxed_deserializer_ident =
1224 boxed_deserializer_ident(config.boxed_deserializer, deserializer_ident);
1225 let init_deserializer = if is_defaultable {
1226 quote! { #boxed_deserializer_ident::default() }
1227 } else {
1228 quote! {
1229 #boxed_deserializer_ident {
1230 state__: #box_::new(#deserializer_state_ident::Init__),
1231 }
1232 }
1233 };
1234 let init_deserializer = ctx.do_box(config.boxed_deserializer, init_deserializer);
1235
1236 quote! {
1237 let deserializer = #init_deserializer;
1238 let mut output = deserializer.next(helper, event)?;
1239
1240 output.artifact = match output.artifact {
1241 #deserializer_artifact::Deserializer(x) if matches!(&*x.state__, #deserializer_state_ident::Init__) => #deserializer_artifact::None,
1242 artifact => artifact,
1243 };
1244
1245 Ok(output)
1246 }
1247 }
1248
1249 fn render_deserializer_fn_next(&self, ctx: &Context<'_, '_>) -> TokenStream {
1250 let config = ctx.get_ref::<DeserializerConfig>();
1251
1252 let deserializer_ident =
1253 boxed_deserializer_ident(config.boxed_deserializer, &self.deserializer_ident);
1254 let deserializer_state_ident = &self.deserializer_state_ident;
1255 let (event_at, return_end_event) = self.return_end_event(ctx);
1256
1257 let event = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Event");
1258 let replace = resolve_quick_xml_ident!(ctx, "::core::mem::replace");
1259 let deserializer_event =
1260 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerEvent");
1261 let deserializer_output =
1262 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerOutput");
1263 let deserializer_artifact =
1264 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerArtifact");
1265 let element_handler_output =
1266 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ElementHandlerOutput");
1267
1268 ctx.add_quick_xml_deserialize_usings(true, ["::xsd_parser_types::quick_xml::Deserializer"]);
1269
1270 let handlers_continue = self
1271 .elements
1272 .iter()
1273 .map(|x| x.deserializer_enum_variant_fn_next_continue(ctx));
1274 let handlers_create = self
1275 .elements
1276 .iter()
1277 .map(|x| x.deserializer_enum_variant_fn_next_create(ctx));
1278
1279 let handler_mixed = self.base.is_mixed().then(|| {
1280 quote! {
1281 (state, #event::Text(_) | #event::CData(_)) => {
1282 *self.state__ = state;
1283 break (#deserializer_event::None, false);
1284 }
1285 }
1286 });
1287
1288 quote! {
1289 use #deserializer_state_ident as S;
1290
1291 let mut event = event;
1292
1293 let (event, allow_any) = loop {
1294 let state = #replace(&mut *self.state__, S::Unknown__);
1295 event = match (state, event) {
1296 (S::Unknown__, _) => unreachable!(),
1297 #( #handlers_continue )*
1298 (state, #event_at #event::End(_)) => {
1299 return Ok(#deserializer_output {
1300 artifact: #deserializer_artifact::Data(#deserializer_ident::finish_state(helper, state)?),
1301 event: #return_end_event,
1302 allow_any: false,
1303 });
1304 }
1305 (S::Init__, event) => match self.find_suitable(helper, event)? {
1306 #element_handler_output::Break { event, allow_any } => break (event, allow_any),
1307 #element_handler_output::Continue { event, .. } => event,
1308 },
1309 #( #handlers_create )*
1310 (state @ S::Done__(_), event) => {
1311 *self.state__ = state;
1312
1313 break (#deserializer_event::Continue(event), false);
1314 },
1315 #handler_mixed
1316 (state, event) => {
1317 *self.state__ = state;
1318 break (#deserializer_event::Continue(event), false);
1319 }
1320 }
1321 };
1322
1323 let artifact = if matches!(&*self.state__, S::Done__(_)) {
1324 #deserializer_artifact::Data(self.finish(helper)?)
1325 } else {
1326 #deserializer_artifact::Deserializer(self)
1327 };
1328
1329 Ok(#deserializer_output {
1330 artifact,
1331 event,
1332 allow_any,
1333 })
1334 }
1335 }
1336
1337 fn render_deserializer_fn_finish(&self, ctx: &Context<'_, '_>) -> TokenStream {
1338 let config = ctx.get_ref::<DeserializerConfig>();
1339 let deserializer_ident =
1340 boxed_deserializer_ident(config.boxed_deserializer, &self.deserializer_ident);
1341
1342 quote! {
1343 #deserializer_ident::finish_state(helper, *self.state__)
1344 }
1345 }
1346}
1347
1348impl ComplexDataStruct<'_> {
1349 fn render_deserializer(&self, ctx: &mut Context<'_, '_>) {
1350 self.render_with_deserializer(ctx);
1351 self.render_deserializer_type(ctx);
1352 self.render_deserializer_state_type(ctx);
1353 self.render_deserializer_helper(ctx);
1354 self.render_deserializer_impl(ctx);
1355 }
1356
1357 fn render_deserializer_type(&self, ctx: &mut Context<'_, '_>) {
1358 let deserializer_ident = &self.deserializer_ident;
1359 let deserializer_state_ident = &self.deserializer_state_ident;
1360 let attributes = self
1361 .attributes
1362 .iter()
1363 .map(|x| x.deserializer_struct_field_decl(ctx));
1364 let elements = self
1365 .elements()
1366 .iter()
1367 .map(|x| x.deserializer_struct_field_decl(ctx));
1368 let content = self.content().map(|x| x.deserializer_field_decl(ctx));
1369
1370 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
1371
1372 let code = quote! {
1373 #[derive(Debug)]
1374 pub struct #deserializer_ident {
1375 #( #attributes )*
1376 #( #elements )*
1377 #content
1378 state__: #box_<#deserializer_state_ident>,
1379 }
1380 };
1381
1382 ctx.quick_xml_deserialize().append(code);
1383 }
1384
1385 fn render_deserializer_state_type(&self, ctx: &mut Context<'_, '_>) {
1386 let deserializer_state_ident = &self.deserializer_state_ident;
1387
1388 let variants = match &self.mode {
1389 StructMode::Empty { .. } => {
1390 quote! {
1391 Init__,
1392 Unknown__,
1393 }
1394 }
1395 StructMode::Content { content } => {
1396 let target_type = ctx.resolve_type_for_deserialize_module(&content.target_type);
1397
1398 let with_deserializer = resolve_quick_xml_ident!(
1399 ctx,
1400 "::xsd_parser_types::quick_xml::WithDeserializer"
1401 );
1402
1403 let next = content.need_next_state().then(|| {
1404 quote! {
1405 Next__,
1406 }
1407 });
1408 let done = content.need_done_state(self.represents_element()).then(|| {
1409 quote! {
1410 Done__,
1411 }
1412 });
1413
1414 quote! {
1415 Init__,
1416 #next
1417 Content__(<#target_type as #with_deserializer>::Deserializer),
1418 #done
1419 Unknown__,
1420 }
1421 }
1422 StructMode::All { elements, .. } => {
1423 let variants = elements.iter().map(|element| {
1424 let variant_ident = &element.variant_ident;
1425 let target_type = ctx.resolve_type_for_deserialize_module(&element.target_type);
1426 let with_deserializer = resolve_quick_xml_ident!(
1427 ctx,
1428 "::xsd_parser_types::quick_xml::WithDeserializer"
1429 );
1430
1431 quote! {
1432 #variant_ident(<#target_type as #with_deserializer>::Deserializer),
1433 }
1434 });
1435
1436 quote! {
1437 Init__,
1438 Next__,
1439 #( #variants )*
1440 Unknown__,
1441 }
1442 }
1443 StructMode::Sequence { elements, .. } => {
1444 let variants = elements.iter().map(|element| {
1445 let variant_ident = &element.variant_ident;
1446 let target_type = ctx.resolve_type_for_deserialize_module(&element.target_type);
1447
1448 let option = resolve_build_in!(ctx, "::core::option::Option");
1449
1450 let with_deserializer = resolve_quick_xml_ident!(
1451 ctx,
1452 "::xsd_parser_types::quick_xml::WithDeserializer"
1453 );
1454
1455 quote! {
1456 #variant_ident(#option<<#target_type as #with_deserializer>::Deserializer>),
1457 }
1458 });
1459
1460 quote! {
1461 Init__,
1462 #( #variants )*
1463 Done__,
1464 Unknown__,
1465 }
1466 }
1467 };
1468
1469 let code = quote! {
1470 #[derive(Debug)]
1471 enum #deserializer_state_ident {
1472 #variants
1473 }
1474 };
1475
1476 ctx.quick_xml_deserialize().append(code);
1477 }
1478
1479 fn render_deserializer_helper(&self, ctx: &mut Context<'_, '_>) {
1480 let is_defaultable = ctx.is_defaultable_type();
1481
1482 let type_ident = &self.type_ident;
1483 let represents_element = self.represents_element();
1484 let deserializer_ident = &self.deserializer_ident;
1485 let deserializer_state_ident = &self.deserializer_state_ident;
1486
1487 let fn_find_suitable = matches!(&self.mode, StructMode::All { .. })
1488 .then(|| self.render_deserializer_fn_find_suitable(ctx));
1489 let fn_from_bytes_start = self
1490 .represents_element()
1491 .then(|| self.render_deserializer_fn_from_bytes_start(ctx));
1492 let fn_finish_state = self.render_deserializer_fn_finish_state(ctx);
1493
1494 let store_content = self
1495 .content()
1496 .map(|x| x.deserializer_struct_field_fn_store(ctx));
1497 let handle_content = self.content().map(|x| {
1498 x.deserializer_struct_field_fn_handle(
1499 ctx,
1500 type_ident,
1501 represents_element,
1502 deserializer_state_ident,
1503 )
1504 });
1505
1506 let elements = self.elements();
1507 let store_elements = elements
1508 .iter()
1509 .map(|x| x.deserializer_struct_field_fn_store(ctx))
1510 .collect::<Vec<_>>();
1511 let handle_elements = elements
1512 .iter()
1513 .enumerate()
1514 .map(|(i, x)| {
1515 let next = elements.get(i + 1);
1516
1517 if let StructMode::All { .. } = &self.mode {
1518 x.deserializer_struct_field_fn_handle_all(ctx, deserializer_state_ident)
1519 } else {
1520 x.deserializer_struct_field_fn_handle_sequence(
1521 ctx,
1522 next,
1523 deserializer_state_ident,
1524 )
1525 }
1526 })
1527 .collect::<Vec<_>>();
1528
1529 let impl_default = is_defaultable.then(|| self.render_deserializer_impl_default(ctx));
1530
1531 let code = quote! {
1532 impl #deserializer_ident {
1533 #fn_find_suitable
1534 #fn_from_bytes_start
1535 #fn_finish_state
1536
1537 #store_content
1538 #handle_content
1539
1540 #( #store_elements )*
1541 #( #handle_elements )*
1542 }
1543
1544 #impl_default
1545 };
1546
1547 ctx.quick_xml_deserialize().append(code);
1548 }
1549
1550 fn render_deserializer_fn_find_suitable(&self, ctx: &Context<'_, '_>) -> TokenStream {
1551 let allow_any = self.allow_any();
1552 let deserializer_state_ident = &self.deserializer_state_ident;
1553
1554 let elements = self
1555 .elements()
1556 .iter()
1557 .filter_map(|x| x.deserializer_struct_field_init_element(ctx));
1558 let groups = self
1559 .elements()
1560 .iter()
1561 .filter_map(|x| x.deserializer_struct_field_init_group(ctx, !allow_any))
1562 .collect::<Vec<_>>();
1563
1564 let (allow_any_result, allow_any_decl) = if groups.is_empty() || allow_any {
1565 (quote!(#allow_any), None)
1566 } else {
1567 (
1568 quote!(allow_any_element),
1569 Some(quote!(let mut allow_any_element = false;)),
1570 )
1571 };
1572
1573 let fallback = self
1574 .elements()
1575 .iter()
1576 .find_map(|x| x.deserializer_struct_field_init_text(ctx))
1577 .unwrap_or_else(|| {
1578 let element_handler_output = resolve_quick_xml_ident!(
1579 ctx,
1580 "::xsd_parser_types::quick_xml::ElementHandlerOutput"
1581 );
1582
1583 quote! {
1584 *self.state__ = fallback.take().unwrap_or(#deserializer_state_ident::Init__);
1585
1586 Ok(#element_handler_output::return_to_parent(event, #allow_any_result))
1587 }
1588 });
1589
1590 let result = resolve_build_in!(ctx, "::core::result::Result");
1591 let option = resolve_build_in!(ctx, "::core::option::Option");
1592
1593 let event = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Event");
1594 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
1595 let deserialize_helper =
1596 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
1597 let element_handler_output =
1598 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ElementHandlerOutput");
1599
1600 quote! {
1601 fn find_suitable<'de>(
1602 &mut self,
1603 helper: &mut #deserialize_helper,
1604 event: #event<'de>,
1605 fallback: &mut #option<#deserializer_state_ident>,
1606 ) -> #result<#element_handler_output<'de>, #error> {
1607 #allow_any_decl
1608
1609 if let #event::Start(x) | #event::Empty(x) = &event {
1610 #( #elements )*
1611 #( #groups )*
1612 }
1613
1614 #fallback
1615 }
1616 }
1617 }
1618
1619 #[allow(clippy::too_many_lines)]
1620 fn render_deserializer_fn_from_bytes_start(&self, ctx: &Context<'_, '_>) -> TokenStream {
1621 let config = ctx.get_ref::<DeserializerConfig>();
1622
1623 let deserializer_state_ident = &self.deserializer_state_ident;
1624
1625 let mut index = 0;
1626 let mut any_attribute = None;
1627
1628 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
1629
1630 let attrib_var = self.attributes.iter().map(|x| x.deserializer_var_decl(ctx));
1631 let attrib_match = self
1632 .attributes
1633 .iter()
1634 .filter_map(|x| x.deserializer_matcher(ctx, &mut index, &mut any_attribute))
1635 .collect::<Vec<_>>();
1636 let attrib_init = self
1637 .attributes
1638 .iter()
1639 .map(|x| x.deserializer_struct_field_init(ctx, &self.type_ident));
1640 let element_init = self
1641 .elements()
1642 .iter()
1643 .map(|x| x.deserializer_struct_field_init(ctx));
1644 let content_init = self
1645 .content()
1646 .map(|x| x.deserializer_struct_field_init(ctx));
1647
1648 let has_normal_attributes = index > 0;
1649 let need_default_handler = !self.allow_any_attribute || any_attribute.is_some();
1650 let default_attrib_handler = need_default_handler.then(|| {
1651 let body = any_attribute
1652 .unwrap_or_else(|| quote! { helper.raise_unexpected_attrib_checked(&attrib)?; });
1653
1654 if has_normal_attributes {
1655 quote! {
1656 else {
1657 #body
1658 }
1659 }
1660 } else {
1661 body
1662 }
1663 });
1664
1665 let need_attrib_loop = self.has_attributes() || default_attrib_handler.is_some();
1666 let attrib_loop = need_attrib_loop.then(|| {
1667 quote! {
1668 for attrib in helper.filter_xmlns_attributes(bytes_start) {
1669 let attrib = attrib?;
1670
1671 #( #attrib_match )*
1672
1673 #default_attrib_handler
1674 }
1675 }
1676 });
1677
1678 let self_type = if config.boxed_deserializer {
1679 quote!(#box_<Self>)
1680 } else {
1681 quote!(Self)
1682 };
1683
1684 let self_ctor = if self.represents_element() {
1685 quote! {
1686 Self {
1687 #( #attrib_init )*
1688 #( #element_init )*
1689 #content_init
1690 state__: #box_::new(#deserializer_state_ident::Init__),
1691 }
1692 }
1693 } else {
1694 quote!(Self::default())
1695 };
1696 let self_ctor = ctx.do_box(config.boxed_deserializer, self_ctor);
1697
1698 let result = resolve_build_in!(ctx, "::core::result::Result");
1699
1700 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
1701 let bytes_start =
1702 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::BytesStart");
1703 let deserialize_helper =
1704 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
1705
1706 quote! {
1707 fn from_bytes_start(
1708 helper: &mut #deserialize_helper,
1709 bytes_start: &#bytes_start<'_>
1710 ) -> #result<#self_type, #error> {
1711 #( #attrib_var )*
1712
1713 #attrib_loop
1714
1715 Ok(#self_ctor)
1716 }
1717 }
1718 }
1719
1720 fn render_deserializer_fn_finish_state(&self, ctx: &Context<'_, '_>) -> TokenStream {
1721 let deserializer_state_ident = &self.deserializer_state_ident;
1722
1723 let result = resolve_build_in!(ctx, "::core::result::Result");
1724
1725 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
1726 let deserialize_helper =
1727 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
1728
1729 let body = match &self.mode {
1730 StructMode::All { elements, .. } => {
1731 let elements = elements
1732 .iter()
1733 .map(|x| x.deserializer_struct_field_finish_state_all());
1734
1735 quote! {
1736 use #deserializer_state_ident as S;
1737
1738 match state {
1739 #( #elements )*
1740 _ => (),
1741 }
1742
1743 Ok(())
1744 }
1745 }
1746 StructMode::Sequence { elements, .. } => {
1747 let elements = elements
1748 .iter()
1749 .map(|x| x.deserializer_struct_field_finish_state_sequence());
1750
1751 quote! {
1752 use #deserializer_state_ident as S;
1753
1754 match state {
1755 #( #elements )*
1756 _ => (),
1757 }
1758
1759 Ok(())
1760 }
1761 }
1762 StructMode::Content { .. } => {
1763 quote! {
1764 if let #deserializer_state_ident::Content__(deserializer) = state {
1765 self.store_content(deserializer.finish(helper)?)?;
1766 }
1767
1768 Ok(())
1769 }
1770 }
1771 _ => quote! { Ok(()) },
1772 };
1773
1774 quote! {
1775 fn finish_state(
1776 &mut self,
1777 helper: &mut #deserialize_helper,
1778 state: #deserializer_state_ident
1779 ) -> #result<(), #error> {
1780 #body
1781 }
1782 }
1783 }
1784
1785 fn render_deserializer_impl_default(&self, ctx: &Context<'_, '_>) -> TokenStream {
1786 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
1787 let default = resolve_build_in!(ctx, "::core::default::Default");
1788
1789 let deserializer_ident = &self.deserializer_ident;
1790 let deserializer_state_ident = &self.deserializer_state_ident;
1791
1792 let element_init = self
1793 .elements()
1794 .iter()
1795 .map(|x| x.deserializer_struct_field_init(ctx));
1796 let content_init = self
1797 .content()
1798 .map(|x| x.deserializer_struct_field_init(ctx));
1799
1800 quote! {
1801 impl #default for #deserializer_ident {
1802 fn default() -> Self {
1803 Self {
1804 #( #element_init )*
1805 #content_init
1806 state__: #box_::new(#deserializer_state_ident::Init__),
1807 }
1808 }
1809 }
1810 }
1811 }
1812
1813 fn render_deserializer_impl(&self, ctx: &mut Context<'_, '_>) {
1814 let fn_init = self.render_deserializer_fn_init(ctx);
1815 let fn_next = self.render_deserializer_fn_next(ctx);
1816 let fn_finish = self.render_deserializer_fn_finish(ctx);
1817
1818 self.base
1819 .render_deserializer_impl(ctx, &fn_init, &fn_next, &fn_finish, true);
1820 }
1821
1822 fn render_deserializer_fn_init(&self, ctx: &mut Context<'_, '_>) -> TokenStream {
1823 if matches!(&self.mode, StructMode::Content { content } if content.is_simple()) {
1824 self.render_deserializer_fn_init_simple(ctx)
1825 } else if self.represents_element() {
1826 self.render_deserializer_fn_init_for_element(ctx)
1827 } else {
1828 self.render_deserializer_fn_init_for_group(ctx)
1829 }
1830 }
1831
1832 fn render_deserializer_fn_init_simple(&self, ctx: &Context<'_, '_>) -> TokenStream {
1833 let deserializer_ident = &self.deserializer_ident;
1834 let config = ctx.get_ref::<DeserializerConfig>();
1835 let boxed_deserializer_ident =
1836 boxed_deserializer_ident(config.boxed_deserializer, deserializer_ident);
1837
1838 let event = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Event");
1839 let deserializer_event =
1840 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerEvent");
1841 let deserializer_output =
1842 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerOutput");
1843 let deserializer_artifact =
1844 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerArtifact");
1845
1846 quote! {
1847 let (#event::Start(x) | #event::Empty(x)) = &event else {
1848 return Ok(#deserializer_output {
1849 artifact: #deserializer_artifact::None,
1850 event: #deserializer_event::Break(event),
1851 allow_any: false,
1852 });
1853 };
1854
1855 #boxed_deserializer_ident::from_bytes_start(helper, x)?.next(helper, event)
1856 }
1857 }
1858
1859 fn render_deserializer_fn_init_for_group(&self, ctx: &Context<'_, '_>) -> TokenStream {
1860 let config = ctx.get_ref::<DeserializerConfig>();
1861 let deserializer_ident = &self.deserializer_ident;
1862 let boxed_deserializer_ident =
1863 boxed_deserializer_ident(config.boxed_deserializer, deserializer_ident);
1864 let deserializer_state_ident = &self.deserializer_state_ident;
1865
1866 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
1867
1868 let deserializer_artifact =
1869 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerArtifact");
1870
1871 let element_init = self
1872 .elements()
1873 .iter()
1874 .map(|x| x.deserializer_struct_field_init(ctx));
1875 let content_init = self
1876 .content()
1877 .map(|x| x.deserializer_struct_field_init(ctx));
1878 let init_deserializer = ctx.do_box(
1879 config.boxed_deserializer,
1880 quote! {
1881 #boxed_deserializer_ident {
1882 #( #element_init )*
1883 #content_init
1884 state__: #box_::new(#deserializer_state_ident::Init__),
1885 }
1886 },
1887 );
1888
1889 quote! {
1890 let deserializer = #init_deserializer;
1891 let mut output = deserializer.next(helper, event)?;
1892
1893 output.artifact = match output.artifact {
1894 #deserializer_artifact::Deserializer(x)
1895 if matches!(&*x.state__, #deserializer_state_ident::Init__)
1896 => #deserializer_artifact::None,
1897 artifact => artifact,
1898 };
1899
1900 Ok(output)
1901 }
1902 }
1903
1904 fn render_deserializer_fn_next(&self, ctx: &Context<'_, '_>) -> TokenStream {
1905 match &self.mode {
1906 StructMode::Empty { allow_any } => {
1907 self.render_deserializer_fn_next_empty(ctx, *allow_any)
1908 }
1909 StructMode::Content { content } => {
1910 if content.is_simple() {
1911 self.render_deserializer_fn_next_content_simple(ctx)
1912 } else {
1913 self.render_deserializer_fn_next_content_complex(ctx, content)
1914 }
1915 }
1916 StructMode::All { .. } => self.render_deserializer_fn_next_all(ctx),
1917 StructMode::Sequence { .. } => self.render_deserializer_fn_next_sequence(ctx),
1918 }
1919 }
1920
1921 fn render_deserializer_fn_next_empty(
1922 &self,
1923 ctx: &Context<'_, '_>,
1924 allow_any: bool,
1925 ) -> TokenStream {
1926 let _self = self;
1927 let (_, return_end_event) = self.return_end_event(ctx);
1928
1929 let event = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Event");
1930 let deserializer_event =
1931 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerEvent");
1932 let deserializer_output =
1933 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerOutput");
1934 let deserializer_artifact =
1935 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerArtifact");
1936
1937 ctx.add_quick_xml_deserialize_usings(true, ["::xsd_parser_types::quick_xml::Deserializer"]);
1938
1939 let mixed_handler = self.base.is_mixed().then(|| {
1940 quote! {
1941 else if matches!(&event, #event::Text(_) | #event::CData(_)) {
1942 Ok(#deserializer_output {
1943 artifact: #deserializer_artifact::Deserializer(self),
1944 event: #deserializer_event::None,
1945 allow_any: #allow_any,
1946 })
1947 }
1948 }
1949 });
1950
1951 quote! {
1952 if let #event::End(_) = &event {
1953 Ok(#deserializer_output {
1954 artifact: #deserializer_artifact::Data(self.finish(helper)?),
1955 event: #return_end_event,
1956 allow_any: false,
1957 })
1958 }
1959 #mixed_handler
1960 else {
1961 Ok(#deserializer_output {
1962 artifact: #deserializer_artifact::Deserializer(self),
1963 event: #deserializer_event::Break(event),
1964 allow_any: #allow_any,
1965 })
1966 }
1967 }
1968 }
1969
1970 fn render_deserializer_fn_next_content_simple(&self, ctx: &Context<'_, '_>) -> TokenStream {
1971 let deserializer_state_ident = &self.deserializer_state_ident;
1972
1973 let replace = resolve_quick_xml_ident!(ctx, "::core::mem::replace");
1974 let content_deserializer =
1975 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ContentDeserializer");
1976
1977 ctx.add_quick_xml_deserialize_usings(true, ["::xsd_parser_types::quick_xml::Deserializer"]);
1978
1979 quote! {
1980 use #deserializer_state_ident as S;
1981
1982 match #replace(&mut *self.state__, S::Unknown__) {
1983 S::Unknown__ => unreachable!(),
1984 S::Init__ => {
1985 let output = #content_deserializer::init(helper, event)?;
1986 self.handle_content(helper, output)
1987 }
1988 S::Content__(deserializer) => {
1989 let output = deserializer.next(helper, event)?;
1990 self.handle_content(helper, output)
1991 }
1992 }
1993 }
1994 }
1995
1996 fn render_deserializer_fn_next_content_complex(
1997 &self,
1998 ctx: &Context<'_, '_>,
1999 content: &ComplexDataContent<'_>,
2000 ) -> TokenStream {
2001 let target_type = ctx.resolve_type_for_deserialize_module(&content.target_type);
2002 let (event_at, return_end_event) = self.return_end_event(ctx);
2003 let deserializer_state_ident = &self.deserializer_state_ident;
2004
2005 let event = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Event");
2006 let replace = resolve_quick_xml_ident!(ctx, "::core::mem::replace");
2007 let with_deserializer =
2008 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::WithDeserializer");
2009 let deserializer_event =
2010 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerEvent");
2011 let deserializer_output =
2012 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerOutput");
2013 let deserializer_artifact =
2014 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerArtifact");
2015 let element_handler_output =
2016 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ElementHandlerOutput");
2017
2018 ctx.add_quick_xml_deserialize_usings(true, ["::xsd_parser_types::quick_xml::Deserializer"]);
2019
2020 let has_done_state = content.need_done_state(self.represents_element());
2021 let done_handler = has_done_state.then(|| {
2022 quote! {
2023 (S::Done__, event) => {
2024 *self.state__ = S::Done__;
2025
2026 break (#deserializer_event::Continue(event), false);
2027 },
2028 }
2029 });
2030 let artifact_handler = if has_done_state {
2031 quote! {
2032 let artifact = match &*self.state__ {
2033 S::Done__ => #deserializer_artifact::Data(self.finish(helper)?),
2034 _ => #deserializer_artifact::Deserializer(self),
2035 };
2036 }
2037 } else {
2038 quote! {
2039 let artifact = #deserializer_artifact::Deserializer(self);
2040 }
2041 };
2042
2043 quote! {
2044 use #deserializer_state_ident as S;
2045
2046 let mut event = event;
2047 let mut fallback = None;
2048
2049 let (event, allow_any) = loop {
2050 let state = #replace(&mut *self.state__, S::Unknown__);
2051
2052 event = match (state, event) {
2053 (S::Unknown__, _) => unreachable!(),
2054 (S::Content__(deserializer), event) => {
2055 let output = deserializer.next(helper, event)?;
2056 match self.handle_content(helper, output, &mut fallback)? {
2057 #element_handler_output::Break { event, allow_any } => break (event, allow_any),
2058 #element_handler_output::Continue { event, .. } => event,
2059 }
2060 }
2061 (_, #event_at #event::End(_)) => {
2062 return Ok(#deserializer_output {
2063 artifact: #deserializer_artifact::Data(self.finish(helper)?),
2064 event: #return_end_event,
2065 allow_any: false,
2066 });
2067 }
2068 (state @ (S::Init__ | S::Next__), event) => {
2069 fallback.get_or_insert(state);
2070 let output = <#target_type as #with_deserializer>::init(helper, event)?;
2071 match self.handle_content(helper, output, &mut fallback)? {
2072 #element_handler_output::Break { event, allow_any } => break (event, allow_any),
2073 #element_handler_output::Continue { event, .. } => event,
2074 }
2075 },
2076 #done_handler
2077 }
2078 };
2079
2080 if let Some(fallback) = fallback {
2081 *self.state__ = fallback;
2082 }
2083
2084 #artifact_handler
2085
2086 Ok(#deserializer_output {
2087 artifact,
2088 event,
2089 allow_any,
2090 })
2091 }
2092 }
2093
2094 fn render_deserializer_fn_next_all(&self, ctx: &Context<'_, '_>) -> TokenStream {
2095 let (event_at, return_end_event) = self.return_end_event(ctx);
2096 let deserializer_state_ident = &self.deserializer_state_ident;
2097
2098 let event = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Event");
2099 let replace = resolve_quick_xml_ident!(ctx, "::core::mem::replace");
2100 let deserializer_output =
2101 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerOutput");
2102 let deserializer_artifact =
2103 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerArtifact");
2104 let element_handler_output =
2105 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ElementHandlerOutput");
2106
2107 let handlers = self
2108 .elements()
2109 .iter()
2110 .map(|x| x.deserializer_struct_field_fn_next_all(ctx));
2111
2112 quote! {
2113 use #deserializer_state_ident as S;
2114
2115 let mut event = event;
2116 let mut fallback = None;
2117
2118 let (event, allow_any) = loop {
2119 let state = #replace(&mut *self.state__, S::Unknown__);
2120
2121 event = match (state, event) {
2122 (S::Unknown__, _) => unreachable!(),
2123 #( #handlers )*
2124 (_, #event_at #event::End(_)) => {
2125 return Ok(#deserializer_output {
2126 artifact: #deserializer_artifact::Data(self.finish(helper)?),
2127 event: #return_end_event,
2128 allow_any: false,
2129 });
2130 }
2131 (state @ (S::Init__ | S::Next__), event) => {
2132 fallback.get_or_insert(state);
2133 match self.find_suitable(helper, event, &mut fallback)? {
2134 #element_handler_output::Continue { event, .. } => event,
2135 #element_handler_output::Break { event, allow_any } => break (event, allow_any),
2136 }
2137 },
2138 }
2139 };
2140
2141 if let Some(fallback) = fallback {
2142 *self.state__ = fallback;
2143 }
2144
2145 Ok(#deserializer_output {
2146 artifact: #deserializer_artifact::Deserializer(self),
2147 event,
2148 allow_any,
2149 })
2150 }
2151 }
2152
2153 #[allow(clippy::too_many_lines)]
2154 fn render_deserializer_fn_next_sequence(&self, ctx: &Context<'_, '_>) -> TokenStream {
2155 let elements = self.elements();
2156 let allow_any = self.allow_any();
2157 let (event_at, return_end_event) = self.return_end_event(ctx);
2158 let deserializer_state_ident = &self.deserializer_state_ident;
2159
2160 let event = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Event");
2161 let replace = resolve_quick_xml_ident!(ctx, "::core::mem::replace");
2162 let deserializer_event =
2163 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerEvent");
2164 let deserializer_output =
2165 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerOutput");
2166 let deserializer_artifact =
2167 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerArtifact");
2168
2169 let text_only = elements.iter().all(|el| el.meta().is_text());
2170 let first = elements
2171 .first()
2172 .expect("`Sequence` should always have at least one element!");
2173 let first_ident = &first.variant_ident;
2174
2175 let handlers_continue = elements
2176 .iter()
2177 .map(|x| x.deserializer_struct_field_fn_next_sequence_continue(ctx));
2178 let handlers_create = elements.iter().enumerate().map(|(i, x)| {
2179 let next = elements.get(i + 1);
2180
2181 x.deserializer_struct_field_fn_next_sequence_create(ctx, next, allow_any)
2182 });
2183
2184 let any_retry = self.has_any().then(|| {
2185 quote! {
2186 let mut is_any_retry = false;
2187 let mut any_fallback = None;
2188 }
2189 });
2190
2191 let init_set_any = allow_any.then(|| {
2192 quote! {
2193 allow_any_element = true;
2194 }
2195 });
2196
2197 let done_allow_any = if allow_any {
2198 quote!(true)
2199 } else {
2200 quote!(allow_any_element)
2201 };
2202
2203 let mut handle_done = quote! {
2204 *self.state__ = S::Done__;
2205 break (#deserializer_event::Continue(event), #done_allow_any);
2206 };
2207
2208 if self.has_any() {
2209 handle_done = quote! {
2210 if let Some(state) = any_fallback.take() {
2211 is_any_retry = true;
2212
2213 *self.state__ = state;
2214
2215 event
2216 } else {
2217 #handle_done
2218 }
2219 };
2220 }
2221
2222 let handler_mixed = (!text_only && self.base.is_mixed()).then(|| {
2223 quote! {
2224 (state, #event::Text(_) | #event::CData(_)) => {
2225 *self.state__ = state;
2226 break (#deserializer_event::None, false);
2227 }
2228 }
2229 });
2230
2231 let handler_fallback = text_only.not().then(|| {
2232 quote! {
2233 (state, event) => {
2234 *self.state__ = state;
2235 break (#deserializer_event::Break(event), false);
2236 }
2237 }
2238 });
2239
2240 quote! {
2241 use #deserializer_state_ident as S;
2242
2243 let mut event = event;
2244 let mut fallback = None;
2245 let mut allow_any_element = false;
2246 #any_retry
2247
2248 let (event, allow_any) = loop {
2249 let state = #replace(&mut *self.state__, S::Unknown__);
2250
2251 event = match (state, event) {
2252 (S::Unknown__, _) => unreachable!(),
2253 #( #handlers_continue )*
2254 (_, #event_at #event::End(_)) => {
2255 if let Some(fallback) = fallback.take() {
2256 self.finish_state(helper, fallback)?;
2257 }
2258
2259 return Ok(#deserializer_output {
2260 artifact: #deserializer_artifact::Data(self.finish(helper)?),
2261 event: #return_end_event,
2262 allow_any: false,
2263 });
2264 }
2265 (S::Init__, event) => {
2266 #init_set_any
2267
2268 fallback.get_or_insert(S::Init__);
2269
2270 *self.state__ = S::#first_ident(None);
2271
2272 event
2273 },
2274 #( #handlers_create )*
2275 (S::Done__, event) => {
2276 #handle_done
2277 },
2278 #handler_mixed
2279 #handler_fallback
2280 }
2281 };
2282
2283 if let Some(fallback) = fallback {
2284 *self.state__ = fallback;
2285 }
2286
2287 Ok(#deserializer_output {
2288 artifact: #deserializer_artifact::Deserializer(self),
2289 event,
2290 allow_any,
2291 })
2292 }
2293 }
2294
2295 fn render_deserializer_fn_finish(&self, ctx: &mut Context<'_, '_>) -> TokenStream {
2296 let type_ident = &self.type_ident;
2297 let deserializer_state_ident = &self.deserializer_state_ident;
2298
2299 let attributes = self
2300 .attributes
2301 .iter()
2302 .map(ComplexDataAttribute::deserializer_struct_field_finish);
2303 let elements = self
2304 .elements()
2305 .iter()
2306 .map(|x| x.deserializer_struct_field_finish(ctx))
2307 .collect::<Vec<_>>();
2308 let content = self
2309 .content()
2310 .map(|x| x.deserializer_struct_field_finish(ctx));
2311
2312 let replace = resolve_quick_xml_ident!(ctx, "::core::mem::replace");
2313
2314 quote! {
2315 let state = #replace(&mut *self.state__, #deserializer_state_ident::Unknown__);
2316 self.finish_state(helper, state)?;
2317
2318 Ok(super::#type_ident {
2319 #( #attributes )*
2320 #( #elements )*
2321 #content
2322 })
2323 }
2324 }
2325}
2326
2327impl ComplexDataContent<'_> {
2328 fn need_next_state(&self) -> bool {
2329 !self.is_simple()
2330 }
2331
2332 fn need_done_state(&self, represents_element: bool) -> bool {
2333 !self.is_simple() && !represents_element && self.max_occurs.is_bounded()
2334 }
2335
2336 fn deserializer_field_decl(&self, ctx: &Context<'_, '_>) -> TokenStream {
2337 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
2338
2339 let target_type = match self.occurs {
2340 Occurs::Single | Occurs::Optional => {
2341 let option = resolve_build_in!(ctx, "::core::option::Option");
2342
2343 quote!(#option<#target_type>)
2344 }
2345 Occurs::DynamicList | Occurs::StaticList(_) => {
2346 let vec = resolve_build_in!(ctx, "::alloc::vec::Vec");
2347
2348 quote!(#vec<#target_type>)
2349 }
2350 e => crate::unreachable!("{:?}", e),
2351 };
2352
2353 quote! {
2354 content: #target_type,
2355 }
2356 }
2357
2358 fn deserializer_struct_field_init(&self, ctx: &Context<'_, '_>) -> TokenStream {
2359 match self.occurs {
2360 Occurs::None => quote!(),
2361 Occurs::Single | Occurs::Optional => quote!(content: None,),
2362 Occurs::DynamicList | Occurs::StaticList(_) => {
2363 let vec = resolve_build_in!(ctx, "::alloc::vec::Vec");
2364
2365 quote!(content: #vec::new(),)
2366 }
2367 }
2368 }
2369
2370 fn deserializer_struct_field_finish(&self, ctx: &mut Context<'_, '_>) -> TokenStream {
2371 let convert = match self.occurs {
2372 Occurs::None => crate::unreachable!(),
2373 Occurs::Single => {
2374 if ctx.has_defaultable_content() {
2375 quote!(helper.finish_default(self.content)?)
2376 } else {
2377 quote!(helper.finish_content(self.content)?)
2378 }
2379 }
2380 Occurs::Optional => {
2381 quote! { self.content }
2382 }
2383 Occurs::DynamicList => {
2384 let min = self.min_occurs;
2385 let max = self.max_occurs.render_opt();
2386
2387 if ctx.has_defaultable_content() {
2388 quote!(helper.finish_vec_default(#min, self.content)?)
2389 } else {
2390 quote!(helper.finish_vec(#min, #max, self.content)?)
2391 }
2392 }
2393 Occurs::StaticList(sz) => {
2394 if ctx.has_defaultable_content() {
2395 quote!(helper.finish_arr_default::<_, #sz>(self.content)?)
2396 } else {
2397 quote!(helper.finish_arr::<_, #sz>(self.content)?)
2398 }
2399 }
2400 };
2401
2402 quote! {
2403 content: #convert,
2404 }
2405 }
2406
2407 fn deserializer_struct_field_fn_store(&self, ctx: &Context<'_, '_>) -> TokenStream {
2408 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
2409
2410 let body = match self.occurs {
2411 Occurs::None => crate::unreachable!(),
2412 Occurs::Single | Occurs::Optional => {
2413 let error_kind =
2414 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ErrorKind");
2415
2416 quote! {
2417 if self.content.is_some() {
2418 Err(#error_kind::DuplicateContent)?;
2419 }
2420
2421 self.content = Some(value);
2422 }
2423 }
2424 Occurs::DynamicList | Occurs::StaticList(_) => quote! {
2425 self.content.push(value);
2426 },
2427 };
2428
2429 let result = resolve_build_in!(ctx, "::core::result::Result");
2430
2431 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
2432
2433 quote! {
2434 fn store_content(&mut self, value: #target_type) -> #result<(), #error> {
2435 #body
2436
2437 Ok(())
2438 }
2439 }
2440 }
2441
2442 fn deserializer_struct_field_fn_handle(
2443 &self,
2444 ctx: &mut Context<'_, '_>,
2445 type_ident: &Ident2,
2446 represents_element: bool,
2447 deserializer_state_ident: &Ident2,
2448 ) -> TokenStream {
2449 if self.is_simple() {
2450 self.deserializer_struct_field_fn_handle_simple(
2451 ctx,
2452 type_ident,
2453 deserializer_state_ident,
2454 )
2455 } else {
2456 self.deserializer_struct_field_fn_handle_complex(
2457 ctx,
2458 represents_element,
2459 deserializer_state_ident,
2460 )
2461 }
2462 }
2463
2464 fn deserializer_struct_field_fn_handle_simple(
2465 &self,
2466 ctx: &Context<'_, '_>,
2467 type_ident: &Ident2,
2468 deserializer_state_ident: &Ident2,
2469 ) -> TokenStream {
2470 assert!(self.is_simple());
2471 assert_eq!(self.min_occurs, 1);
2472 assert_eq!(self.max_occurs, MaxOccurs::Bounded(1));
2473
2474 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
2475
2476 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
2477 let config = ctx.get_ref::<DeserializerConfig>();
2478 let self_type = config.boxed_deserializer.then(|| quote!(: #box_<Self>));
2479
2480 let deserialize_helper =
2481 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
2482 let deserializer_result =
2483 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerResult");
2484 let deserializer_output =
2485 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerOutput");
2486 let deserializer_artifact =
2487 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerArtifact");
2488
2489 quote! {
2490 fn handle_content<'de>(
2491 mut self #self_type,
2492 helper: &mut #deserialize_helper,
2493 output: #deserializer_output<'de, #target_type>,
2494 ) -> #deserializer_result<'de, super::#type_ident> {
2495 use #deserializer_state_ident as S;
2496
2497 let #deserializer_output { artifact, event, allow_any } = output;
2498
2499 match artifact {
2500 #deserializer_artifact::None => Ok(#deserializer_output {
2501 artifact: #deserializer_artifact::None,
2502 event,
2503 allow_any,
2504 }),
2505 #deserializer_artifact::Data(data) => {
2506 self.store_content(data)?;
2507 let data = self.finish(helper)?;
2508
2509 Ok(#deserializer_output {
2510 artifact: #deserializer_artifact::Data(data),
2511 event,
2512 allow_any,
2513 })
2514 }
2515 #deserializer_artifact::Deserializer(deserializer) => {
2516 *self.state__ = S::Content__(deserializer);
2517
2518 Ok(#deserializer_output {
2519 artifact: #deserializer_artifact::Deserializer(self),
2520 event,
2521 allow_any,
2522 })
2523 }
2524 }
2525 }
2526 }
2527 }
2528
2529 #[allow(clippy::too_many_lines)]
2530 fn deserializer_struct_field_fn_handle_complex(
2531 &self,
2532 ctx: &mut Context<'_, '_>,
2533 represents_element: bool,
2534 deserializer_state_ident: &Ident2,
2535 ) -> TokenStream {
2536 assert!(!self.is_simple());
2537
2538 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
2539
2540 let result = resolve_build_in!(ctx, "::core::result::Result");
2541 let option = resolve_build_in!(ctx, "::core::option::Option");
2542 let usize_ = resolve_build_in!(ctx, "::core::primitive::usize");
2543
2544 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
2545 let deserialize_helper =
2546 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
2547 let deserializer_output =
2548 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerOutput");
2549 let deserializer_artifact =
2550 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerArtifact");
2551 let element_handler_output =
2552 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ElementHandlerOutput");
2553
2554 let min = self.min_occurs;
2557 let is_defaultable = self.min_occurs == 0 || ctx.has_defaultable_content();
2558 let none_handler = match (represents_element, is_defaultable, self.occurs) {
2559 (_, _, Occurs::None) => unreachable!(),
2560 (false, true, _) => quote! {
2563 *self.state__ = fallback.take().unwrap_or(S::Next__);
2564
2565 return Ok(#element_handler_output::break_(event, allow_any));
2566 },
2567 (false, false, Occurs::Single | Occurs::Optional) => quote! {
2571 *self.state__ = S::Init__;
2572
2573 return Ok(#element_handler_output::break_(event, allow_any));
2574 },
2575 (false, false, Occurs::DynamicList | Occurs::StaticList(_)) => quote! {
2579 *self.state__ = fallback.take().unwrap_or(S::Next__);
2580
2581 let len = self.content.len() + #usize_::from(matches!(*self.state__, S::Content__(_)));
2582 if len < #min {
2583 return Ok(#element_handler_output::return_to_root(event, allow_any));
2584 } else {
2585 return Ok(#element_handler_output::break_(event, allow_any));
2586 }
2587 },
2588 (true, _, _) => quote! {
2592 *self.state__ = fallback.take().unwrap_or(S::Next__);
2593
2594 return Ok(#element_handler_output::from_event_end(event, allow_any));
2595 },
2596 };
2597
2598 let data_handler = match (represents_element, self.occurs, self.max_occurs) {
2600 (_, Occurs::None, _) => unreachable!(),
2601 (false, Occurs::Single | Occurs::Optional, _) => quote! {
2603 *self.state__ = S::Done__;
2604
2605 Ok(#element_handler_output::break_(event, allow_any))
2606 },
2607 (false, Occurs::DynamicList | Occurs::StaticList(_), MaxOccurs::Bounded(max)) => {
2610 quote! {
2611 if self.content.len() < #max {
2612 *self.state__ = S::Next__;
2613
2614 Ok(#element_handler_output::from_event(event, allow_any))
2615 } else {
2616 *self.state__ = S::Done__;
2617
2618 Ok(#element_handler_output::break_(event, allow_any))
2619 }
2620 }
2621 }
2622 (_, _, _) => quote! {
2626 *self.state__ = S::Next__;
2627
2628 Ok(#element_handler_output::from_event(event, allow_any))
2629 },
2630 };
2631
2632 #[allow(clippy::match_bool)]
2634 let break_or_end = match represents_element {
2635 true => quote!(from_event_end),
2636 false => quote!(break_),
2637 };
2638 let deserializer_handler = match (self.occurs, self.max_occurs) {
2639 (Occurs::None, _) => unreachable!(),
2640 (Occurs::Single | Occurs::Optional, _) => {
2642 quote! {
2643 *self.state__ = S::Content__(deserializer);
2644
2645 Ok(#element_handler_output::#break_or_end(event, allow_any))
2646 }
2647 }
2648 (Occurs::DynamicList | Occurs::StaticList(_), MaxOccurs::Bounded(max)) => {
2652 assert!(max >= 2);
2653 let max_minus_one = max - 1;
2654
2655 quote! {
2656 if self.content.len() < #max_minus_one {
2657 *fallback = Some(S::Content__(deserializer));
2658 *self.state__ = S::Next__;
2659
2660 Ok(#element_handler_output::from_event(event, allow_any))
2661 } else {
2662 *self.state__ = S::Content__(deserializer);
2663
2664 Ok(#element_handler_output::#break_or_end(event, allow_any))
2665 }
2666 }
2667 }
2668 (Occurs::DynamicList | Occurs::StaticList(_), _) => quote! {
2670 *fallback = Some(S::Content__(deserializer));
2671 *self.state__ = S::Next__;
2672
2673 Ok(#element_handler_output::from_event(event, allow_any))
2674 },
2675 };
2676
2677 quote! {
2678 fn handle_content<'de>(
2679 &mut self,
2680 helper: &mut #deserialize_helper,
2681 output: #deserializer_output<'de, #target_type>,
2682 fallback: &mut #option<#deserializer_state_ident>,
2683 ) -> #result<#element_handler_output<'de>, #error> {
2684 use #deserializer_state_ident as S;
2685
2686 let #deserializer_output {
2687 artifact,
2688 event,
2689 allow_any,
2690 } = output;
2691
2692 if artifact.is_none() {
2693 #none_handler
2694 }
2695
2696 if let Some(fallback) = fallback.take() {
2697 self.finish_state(helper, fallback)?;
2698 }
2699
2700 match artifact {
2701 #deserializer_artifact::None => unreachable!(),
2702 #deserializer_artifact::Data(data) => {
2703 self.store_content(data)?;
2704
2705 #data_handler
2706 }
2707 #deserializer_artifact::Deserializer(deserializer) => {
2708 #deserializer_handler
2709 }
2710 }
2711 }
2712 }
2713 }
2714}
2715
2716impl ComplexDataAttribute<'_> {
2717 fn deserializer_matcher(
2718 &self,
2719 ctx: &Context<'_, '_>,
2720 index: &mut usize,
2721 any_attribute: &mut Option<TokenStream>,
2722 ) -> Option<TokenStream> {
2723 let b_name = &self.b_name;
2724 let field_ident = &self.ident;
2725
2726 let else_ = (*index).gt(&0).then(|| quote!(else));
2727
2728 if self.meta.is_any() {
2729 *any_attribute = Some(quote! {
2730 #field_ident.push(attrib)?;
2731 });
2732
2733 None
2734 } else if let Some(module) = self
2735 .meta
2736 .ident
2737 .ns
2738 .and_then(|ns| ctx.types.meta.types.modules.get(&ns))
2739 {
2740 let ns_name = ctx.resolve_type_for_deserialize_module(&module.make_ns_const());
2741
2742 *index += 1;
2743
2744 Some(quote! {
2745 #else_ if matches!(helper.resolve_local_name(attrib.key, &#ns_name), Some(#b_name)) {
2746 helper.read_attrib(&mut #field_ident, #b_name, &attrib.value)?;
2747 }
2748 })
2749 } else {
2750 *index += 1;
2751
2752 Some(quote! {
2753 #else_ if attrib.key.local_name().as_ref() == #b_name {
2754 helper.read_attrib(&mut #field_ident, #b_name, &attrib.value)?;
2755 }
2756 })
2757 }
2758 }
2759
2760 fn deserializer_var_decl(&self, ctx: &Context<'_, '_>) -> TokenStream {
2761 let field_ident = &self.ident;
2762 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
2763
2764 if self.meta.is_any() {
2765 quote!(let mut #field_ident = #target_type::default();)
2766 } else {
2767 let option = resolve_build_in!(ctx, "::core::option::Option");
2768
2769 quote!(let mut #field_ident: #option<#target_type> = None;)
2770 }
2771 }
2772
2773 fn deserializer_struct_field_decl(&self, ctx: &Context<'_, '_>) -> TokenStream {
2774 let field_ident = &self.ident;
2775 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
2776
2777 let target_type = if self.is_option {
2778 let option = resolve_build_in!(ctx, "::core::option::Option");
2779
2780 quote!(#option<#target_type>)
2781 } else {
2782 target_type
2783 };
2784
2785 quote! {
2786 #field_ident: #target_type,
2787 }
2788 }
2789
2790 fn deserializer_struct_field_init(
2791 &self,
2792 ctx: &Context<'_, '_>,
2793 type_ident: &Ident2,
2794 ) -> TokenStream {
2795 let field_ident = &self.ident;
2796
2797 let convert = if self.meta.is_any() {
2798 None
2799 } else if self.default_value.is_some() {
2800 let default_fn_ident = format_ident!("default_{field_ident}");
2801
2802 Some(quote! { .unwrap_or_else(super::#type_ident::#default_fn_ident) })
2803 } else if self.meta.use_ == Use::Required {
2804 let name = &self.s_name;
2805
2806 let error_kind =
2807 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ErrorKind");
2808
2809 Some(quote! { .ok_or_else(|| #error_kind::MissingAttribute(#name.into()))? })
2810 } else {
2811 None
2812 };
2813
2814 quote! {
2815 #field_ident: #field_ident #convert,
2816 }
2817 }
2818
2819 fn deserializer_struct_field_finish(&self) -> TokenStream {
2820 let field_ident = &self.ident;
2821
2822 quote! {
2823 #field_ident: self.#field_ident,
2824 }
2825 }
2826}
2827
2828impl ComplexDataElement<'_> {
2829 fn store_ident(&self) -> Ident2 {
2830 let ident = self.field_ident.to_string();
2831 let ident = ident.trim_start_matches('_');
2832
2833 format_ident!("store_{ident}")
2834 }
2835
2836 fn handler_ident(&self) -> Ident2 {
2837 let ident = self.field_ident.to_string();
2838 let ident = ident.trim_start_matches('_');
2839
2840 format_ident!("handle_{ident}")
2841 }
2842
2843 fn target_type_allows_any(&self, types: &MetaTypes) -> bool {
2844 fn walk(types: &MetaTypes, visit: &mut HashSet<Ident>, ident: &Ident) -> bool {
2845 if !visit.insert(ident.clone()) {
2846 return false;
2847 }
2848
2849 match types.get_variant(ident) {
2850 Some(MetaTypeVariant::All(si) | MetaTypeVariant::Choice(si)) => {
2851 for element in &*si.elements {
2852 match &element.variant {
2853 ElementMetaVariant::Text => return false,
2854 ElementMetaVariant::Any { .. } => return true,
2855 ElementMetaVariant::Type { type_, .. } => {
2856 if walk(types, visit, type_) {
2857 return true;
2858 }
2859 }
2860 }
2861 }
2862
2863 false
2864 }
2865 Some(MetaTypeVariant::Sequence(si)) => match si.elements.first() {
2866 None => false,
2867 Some(ElementMeta {
2868 variant: ElementMetaVariant::Any { .. },
2869 ..
2870 }) => true,
2871 Some(ElementMeta {
2872 variant: ElementMetaVariant::Text,
2873 ..
2874 }) => false,
2875 Some(ElementMeta {
2876 variant: ElementMetaVariant::Type { type_, .. },
2877 ..
2878 }) => walk(types, visit, type_),
2879 },
2880 Some(MetaTypeVariant::ComplexType(ComplexMeta {
2881 content: Some(content),
2882 ..
2883 })) => walk(types, visit, content),
2884 Some(MetaTypeVariant::Custom(x)) => x.allow_any(),
2885 _ => false,
2886 }
2887 }
2888
2889 let mut visit = HashSet::new();
2890
2891 match &self.meta().variant {
2892 ElementMetaVariant::Any { .. } => true,
2893 ElementMetaVariant::Type { type_, .. } => walk(types, &mut visit, type_),
2894 ElementMetaVariant::Text => false,
2895 }
2896 }
2897
2898 fn deserializer_init_element(
2899 &self,
2900 ctx: &Context<'_, '_>,
2901 call_handler: &TokenStream,
2902 ) -> Option<TokenStream> {
2903 if !self.treat_as_element() {
2904 return None;
2905 }
2906
2907 let b_name = &self.b_name;
2908 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
2909
2910 let with_deserializer =
2911 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::WithDeserializer");
2912
2913 ctx.add_quick_xml_deserialize_usings(true, ["::xsd_parser_types::quick_xml::Deserializer"]);
2914
2915 let body = quote! {
2916 let output = <#target_type as #with_deserializer>::init(helper, event)?;
2917
2918 return #call_handler;
2919 };
2920
2921 if let Some(module) = self
2922 .meta()
2923 .ident
2924 .ns
2925 .and_then(|ns| ctx.types.meta.types.modules.get(&ns))
2926 {
2927 let ns_name = ctx.resolve_type_for_deserialize_module(&module.make_ns_const());
2928
2929 Some(quote! {
2930 if matches!(helper.resolve_local_name(x.name(), &#ns_name), Some(#b_name)) {
2931 #body
2932 }
2933 })
2934 } else {
2935 Some(quote! {
2936 if x.name().local_name().as_ref() == #b_name {
2937 #body
2938 }
2939 })
2940 }
2941 }
2942
2943 fn deserializer_init_group(
2944 &self,
2945 ctx: &Context<'_, '_>,
2946 handle_any: bool,
2947 call_handler: &TokenStream,
2948 ) -> TokenStream {
2949 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
2950
2951 let with_deserializer =
2952 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::WithDeserializer");
2953 let element_handler_output =
2954 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ElementHandlerOutput");
2955
2956 ctx.add_quick_xml_deserialize_usings(true, ["::xsd_parser_types::quick_xml::Deserializer"]);
2957
2958 let handle_continue = if handle_any {
2959 quote! {
2960 #element_handler_output::Continue { event, allow_any } => {
2961 allow_any_element = allow_any_element || allow_any;
2962
2963 event
2964 },
2965 }
2966 } else {
2967 quote! {
2968 #element_handler_output::Continue { event, .. } => event,
2969 }
2970 };
2971
2972 quote! {
2973 event = {
2974 let output = <#target_type as #with_deserializer>::init(helper, event)?;
2975
2976 match #call_handler? {
2977 #handle_continue
2978 output => { return Ok(output); }
2979 }
2980 };
2981 }
2982 }
2983
2984 fn deserializer_enum_variant_decl(&self, ctx: &Context<'_, '_>) -> TokenStream {
2985 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
2986 let variant_ident = &self.variant_ident;
2987
2988 let with_deserializer =
2989 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::WithDeserializer");
2990
2991 match self.occurs {
2992 Occurs::Single | Occurs::Optional => {
2993 let option = resolve_build_in!(ctx, "::core::option::Option");
2994
2995 quote! {
2996 #variant_ident(
2997 #option<#target_type>,
2998 #option<<#target_type as #with_deserializer>::Deserializer>,
2999 #option<<#target_type as #with_deserializer>::Deserializer>,
3000 ),
3001 }
3002 }
3003 Occurs::DynamicList | Occurs::StaticList(_) => {
3004 let vec = resolve_build_in!(ctx, "::alloc::vec::Vec");
3005 let option = resolve_build_in!(ctx, "::core::option::Option");
3006
3007 quote! {
3008 #variant_ident(
3009 #vec<#target_type>,
3010 #option<<#target_type as #with_deserializer>::Deserializer>,
3011 #option<<#target_type as #with_deserializer>::Deserializer>,
3012 ),
3013 }
3014 }
3015 e => crate::unreachable!("{:?}", e),
3016 }
3017 }
3018
3019 fn deserializer_enum_variant_init_element(&self, ctx: &Context<'_, '_>) -> Option<TokenStream> {
3020 let default = resolve_build_in!(ctx, "::core::default::Default");
3021
3022 let handler_ident = self.handler_ident();
3023 let call_handler = quote!(self.#handler_ident(helper, #default::default(), None, output));
3024
3025 self.deserializer_init_element(ctx, &call_handler)
3026 }
3027
3028 fn deserializer_enum_variant_init_group(
3029 &self,
3030 ctx: &Context<'_, '_>,
3031 handle_any: bool,
3032 ) -> Option<TokenStream> {
3033 if !self.treat_as_group_or_dynamic() {
3034 return None;
3035 }
3036
3037 let default = resolve_build_in!(ctx, "::core::default::Default");
3038
3039 let handler_ident = self.handler_ident();
3040 let call_handler = quote!(self.#handler_ident(helper, #default::default(), None, output));
3041
3042 Some(self.deserializer_init_group(ctx, handle_any, &call_handler))
3043 }
3044
3045 fn deserializer_enum_variant_init_any(&self, ctx: &Context<'_, '_>) -> Option<TokenStream> {
3046 if !self.treat_as_any() {
3047 return None;
3048 }
3049
3050 let default = resolve_build_in!(ctx, "::core::default::Default");
3051
3052 let handler_ident = self.handler_ident();
3053 let call_handler = quote!(self.#handler_ident(helper, #default::default(), None, output));
3054
3055 Some(self.deserializer_init_group(ctx, false, &call_handler))
3056 }
3057
3058 fn deserializer_enum_variant_init_text(&self, ctx: &Context<'_, '_>) -> Option<TokenStream> {
3059 if !self.treat_as_text() {
3060 return None;
3061 }
3062
3063 let default = resolve_build_in!(ctx, "::core::default::Default");
3064
3065 let handler_ident = self.handler_ident();
3066 let call_handler = quote!(self.#handler_ident(helper, #default::default(), None, output));
3067
3068 Some(self.deserializer_init_group(ctx, false, &call_handler))
3069 }
3070
3071 fn deserializer_enum_variant_default(
3072 &self,
3073 ctx: &Context<'_, '_>,
3074 type_ident: &Ident2,
3075 ) -> TokenStream {
3076 let variant_ident = &self.variant_ident;
3077
3078 match self.occurs {
3079 Occurs::None => unreachable!(),
3080 Occurs::Single => {
3081 let value = quote!(helper.finish_default(None)?);
3082 let value = ctx.do_box(self.need_indirection, value);
3083
3084 quote! {
3085 Ok(super::#type_ident::#variant_ident(#value))
3086 }
3087 }
3088 Occurs::Optional => quote!(Ok(super::#type_ident::#variant_ident(None))),
3089 Occurs::DynamicList => {
3090 let min = self.meta().min_occurs;
3091
3092 quote! {
3093 Ok(super::#type_ident::#variant_ident(helper.finish_vec_default(#min, Vec::new())?))
3094 }
3095 }
3096 Occurs::StaticList(sz) => {
3097 let value = quote!(helper.finish_arr_default::<_, #sz>(Vec::new())?);
3098 let value = ctx.do_box(self.need_indirection, value);
3099
3100 quote! {
3101 Ok(super::#type_ident::#variant_ident(#value))
3102 }
3103 }
3104 }
3105 }
3106
3107 fn deserializer_enum_variant_finish(
3108 &self,
3109 ctx: &mut Context<'_, '_>,
3110 type_ident: &Ident2,
3111 deserializer_ident: &Ident2,
3112 ) -> TokenStream {
3113 let name = &self.s_name;
3114 let store_ident = self.store_ident();
3115 let variant_ident = &self.variant_ident;
3116
3117 let convert = match self.occurs {
3118 Occurs::None => crate::unreachable!(),
3119 Occurs::Single => {
3120 let value = if ctx.is_defaultable_element(self.meta()) {
3121 quote!(helper.finish_default(values)?)
3122 } else {
3123 quote!(helper.finish_element(#name, values)?)
3124 };
3125
3126 ctx.do_box(self.need_indirection, value)
3127 }
3128 Occurs::Optional if self.need_indirection => {
3129 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
3130
3131 quote! { values.map(#box_::new) }
3132 }
3133 Occurs::Optional => {
3134 quote! { values }
3135 }
3136 Occurs::DynamicList => {
3137 let min = self.meta().min_occurs;
3138 let max = self.meta().max_occurs.render_opt();
3139
3140 if min == 0 {
3141 quote!(values)
3142 } else if ctx.is_defaultable_element(self.meta()) {
3143 quote!(helper.finish_vec_default(#min, values)?)
3144 } else {
3145 quote!(helper.finish_vec(#min, #max, values)?)
3146 }
3147 }
3148 Occurs::StaticList(sz) => {
3149 let value = if ctx.is_defaultable_element(self.meta()) {
3150 quote!(helper.finish_arr_default::<_, #sz>(values)?)
3151 } else {
3152 quote!(helper.finish_arr::<_, #sz>(values)?)
3153 };
3154
3155 ctx.do_box(self.need_indirection, value)
3156 }
3157 };
3158
3159 quote! {
3160 S::#variant_ident(mut values, None, deserializer) => {
3161 if let Some(deserializer) = deserializer {
3162 let value = deserializer.finish(helper)?;
3163 #deserializer_ident::#store_ident(&mut values, value)?;
3164 }
3165
3166 Ok(super::#type_ident::#variant_ident(#convert))
3167 }
3168 }
3169 }
3170
3171 fn deserializer_enum_variant_fn_store(&self, ctx: &Context<'_, '_>) -> TokenStream {
3172 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
3173
3174 let name = &self.b_name;
3175 let store_ident = self.store_ident();
3176
3177 match self.occurs {
3178 Occurs::None => crate::unreachable!(),
3179 Occurs::Single | Occurs::Optional => {
3180 let result = resolve_build_in!(ctx, "::core::result::Result");
3181 let option = resolve_build_in!(ctx, "::core::option::Option");
3182
3183 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
3184 let error_kind =
3185 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ErrorKind");
3186 let raw_byte_str =
3187 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::RawByteStr");
3188
3189 quote! {
3190 fn #store_ident(values: &mut #option<#target_type>, value: #target_type) -> #result<(), #error> {
3191 if values.is_some() {
3192 Err(#error_kind::DuplicateElement(#raw_byte_str::from_slice(#name)))?;
3193 }
3194
3195 *values = Some(value);
3196
3197 Ok(())
3198 }
3199 }
3200 }
3201 Occurs::DynamicList | Occurs::StaticList(_) => {
3202 let vec = resolve_build_in!(ctx, "::alloc::vec::Vec");
3203 let result = resolve_build_in!(ctx, "::core::result::Result");
3204
3205 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
3206
3207 quote! {
3208 fn #store_ident(values: &mut #vec<#target_type>, value: #target_type) -> #result<(), #error> {
3209 values.push(value);
3210
3211 Ok(())
3212 }
3213 }
3214 }
3215 }
3216 }
3217
3218 #[allow(clippy::too_many_lines)]
3219 fn deserializer_enum_variant_fn_handle(
3220 &self,
3221 ctx: &mut Context<'_, '_>,
3222 represents_element: bool,
3223 deserializer_ident: &Ident2,
3224 deserializer_state_ident: &Ident2,
3225 ) -> TokenStream {
3226 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
3227
3228 let store_ident = self.store_ident();
3229 let handler_ident = self.handler_ident();
3230 let variant_ident = &self.variant_ident;
3231
3232 let result = resolve_build_in!(ctx, "::core::result::Result");
3233 let option = resolve_build_in!(ctx, "::core::option::Option");
3234 let usize_ = resolve_build_in!(ctx, "::core::primitive::usize");
3235
3236 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
3237 let with_deserializer =
3238 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::WithDeserializer");
3239 let deserialize_helper =
3240 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
3241 let deserializer_output =
3242 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerOutput");
3243 let deserializer_artifact =
3244 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerArtifact");
3245 let element_handler_output =
3246 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ElementHandlerOutput");
3247
3248 #[allow(clippy::match_bool)]
3249 let break_or_end = match represents_element {
3250 true => quote!(from_event_end),
3251 false => quote!(break_),
3252 };
3253
3254 #[allow(clippy::if_same_then_else)]
3255 let continue_or_return = if self.treat_as_text() {
3256 quote!(from_event)
3257 } else if self.treat_as_group() {
3258 quote!(from_event)
3259 } else {
3260 quote!(return_to_root)
3261 };
3262
3263 let values = match self.occurs {
3264 Occurs::None => crate::unreachable!(),
3265 Occurs::Single | Occurs::Optional => quote!(#option<#target_type>),
3266 Occurs::DynamicList | Occurs::StaticList(_) => {
3267 let vec = resolve_build_in!(ctx, "::alloc::vec::Vec");
3268
3269 quote!(#vec<#target_type>)
3270 }
3271 };
3272
3273 let min = self.meta().min_occurs;
3276 let is_defaultable = min == 0 || ctx.is_defaultable_element(self.meta());
3277 let none_handler = match (is_defaultable, self.occurs) {
3278 (_, Occurs::None) => unreachable!(),
3279 (_, Occurs::Single | Occurs::Optional) => quote! {
3282 return Ok(#element_handler_output::#continue_or_return(event, allow_any));
3283 },
3284 (true, Occurs::DynamicList | Occurs::StaticList(_)) => quote! {
3289 if fallback.is_none() && values.is_empty() {
3290 *self.state__ = S::Init__;
3291 return Ok(#element_handler_output::#continue_or_return(event, allow_any));
3292 } else {
3293 *self.state__ = S::#variant_ident(values, None, fallback);
3294 return Ok(#element_handler_output::#break_or_end(event, allow_any));
3295 }
3296 },
3297 (false, Occurs::DynamicList | Occurs::StaticList(_)) => quote! {
3303 if fallback.is_none() && values.is_empty() {
3304 *self.state__ = S::Init__;
3305 return Ok(#element_handler_output::#continue_or_return(event, allow_any));
3306 } else if values.len() + #usize_::from(fallback.is_some()) < #min {
3307 *self.state__ = S::#variant_ident(values, None, fallback);
3308 return Ok(#element_handler_output::return_to_root(event, allow_any));
3309 } else {
3310 *self.state__ = S::#variant_ident(values, None, fallback);
3311 return Ok(#element_handler_output::#break_or_end(event, allow_any));
3312 }
3313 },
3314 };
3315
3316 let data_handler = match (represents_element, self.occurs, self.meta().max_occurs) {
3318 (_, Occurs::None, _) => unreachable!(),
3319 (false, Occurs::Single | Occurs::Optional, _) => quote! {
3321 let data = #deserializer_ident::finish_state(helper, S::#variant_ident(values, None, None))?;
3322 *self.state__ = S::Done__(data);
3323
3324 Ok(#element_handler_output::break_(event, allow_any))
3325 },
3326 (false, Occurs::DynamicList | Occurs::StaticList(_), MaxOccurs::Bounded(max)) => {
3329 quote! {
3330 if values.len() < #max {
3331 *self.state__ = S::#variant_ident(values, None, None);
3332
3333 Ok(#element_handler_output::from_event(event, allow_any))
3334 } else {
3335 let data = #deserializer_ident::finish_state(helper, S::#variant_ident(values, None, None))?;
3336 *self.state__ = S::Done__(data);
3337
3338 Ok(#element_handler_output::break_(event, allow_any))
3339 }
3340 }
3341 }
3342 (_, _, _) => quote! {
3344 *self.state__ = S::#variant_ident(values, None, None);
3345
3346 Ok(#element_handler_output::from_event(event, allow_any))
3347 },
3348 };
3349
3350 let deserializer_handler = match (self.occurs, self.meta().max_occurs) {
3352 (Occurs::None, _) => unreachable!(),
3353 (Occurs::Single | Occurs::Optional, _) => quote! {
3355 *self.state__ = S::#variant_ident(values, None, Some(deserializer));
3356
3357 Ok(#element_handler_output::#break_or_end(event, allow_any))
3358 },
3359 (Occurs::DynamicList | Occurs::StaticList(_), MaxOccurs::Bounded(max)) => {
3363 assert!(max >= 2);
3364 let max_minus_one = max - 1;
3365
3366 quote! {
3367 let can_have_more = values.len() < #max_minus_one;
3368 let ret = if can_have_more {
3369 #element_handler_output::from_event(event, allow_any)
3370 } else {
3371 #element_handler_output::#break_or_end(event, allow_any)
3372 };
3373
3374 if can_have_more && ret.is_continue_start_or_empty() {
3375 *self.state__ = S::#variant_ident(values, Some(deserializer), None);
3376 } else {
3377 *self.state__ = S::#variant_ident(values, None, Some(deserializer));
3378 }
3379
3380 Ok(ret)
3381 }
3382 }
3383 (Occurs::DynamicList | Occurs::StaticList(_), _) => quote! {
3385 let ret = #element_handler_output::from_event(event, allow_any);
3386
3387 if ret.is_continue_start_or_empty() {
3388 *self.state__ = S::#variant_ident(values, Some(deserializer), None);
3389 } else {
3390 *self.state__ = S::#variant_ident(values, None, Some(deserializer));
3391 }
3392
3393 Ok(ret)
3394 },
3395 };
3396
3397 quote! {
3398 fn #handler_ident<'de>(
3399 &mut self,
3400 helper: &mut #deserialize_helper,
3401 mut values: #values,
3402 fallback: #option<<#target_type as #with_deserializer>::Deserializer>,
3403 output: #deserializer_output<'de, #target_type>,
3404 ) -> #result<#element_handler_output<'de>, #error> {
3405 use #deserializer_state_ident as S;
3406
3407 let #deserializer_output {
3408 artifact,
3409 event,
3410 allow_any,
3411 } = output;
3412
3413 if artifact.is_none() {
3414 #none_handler
3415 }
3416
3417 if let Some(deserializer) = fallback {
3418 let data = deserializer.finish(helper)?;
3419 #deserializer_ident::#store_ident(&mut values, data)?;
3420 }
3421
3422 match artifact {
3423 #deserializer_artifact::None => unreachable!(),
3424 #deserializer_artifact::Data(data) => {
3425 #deserializer_ident::#store_ident(&mut values, data)?;
3426
3427 #data_handler
3428 }
3429 #deserializer_artifact::Deserializer(deserializer) => {
3430 #deserializer_handler
3431 }
3432 }
3433 }
3434 }
3435 }
3436
3437 fn deserializer_enum_variant_fn_next_continue(&self, ctx: &Context<'_, '_>) -> TokenStream {
3438 let deserializer_matcher = quote!(Some(deserializer));
3439 let event_matcher = quote!(event);
3440 let output = quote!(deserializer.next(helper, event));
3441
3442 self.deserializer_enum_variant_fn_next(ctx, &deserializer_matcher, &event_matcher, &output)
3443 }
3444
3445 fn deserializer_enum_variant_fn_next_create(&self, ctx: &Context<'_, '_>) -> TokenStream {
3446 let name = &self.b_name;
3447 let allow_any = self.target_type_allows_any(ctx.types.meta.types);
3448 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
3449
3450 let event = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Event");
3451 let with_deserializer =
3452 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::WithDeserializer");
3453
3454 let deserializer_matcher = quote!(None);
3455 let event_matcher = quote!(event @ (#event::Start(_) | #event::Empty(_)));
3456
3457 let need_name_matcher = !self.target_is_dynamic
3458 && matches!(
3459 &self.meta().variant,
3460 ElementMetaVariant::Any { .. }
3461 | ElementMetaVariant::Type {
3462 mode: ElementMode::Element,
3463 ..
3464 }
3465 );
3466
3467 let output = if need_name_matcher {
3468 let ns_name = self
3469 .meta()
3470 .ident
3471 .ns
3472 .as_ref()
3473 .and_then(|ns| ctx.types.meta.types.modules.get(ns))
3474 .map(|module| ctx.resolve_type_for_deserialize_module(&module.make_ns_const()))
3475 .map_or_else(|| quote!(None), |ns_name| quote!(Some(&#ns_name)));
3476
3477 quote! {
3478 helper.init_start_tag_deserializer(event, #ns_name, #name, #allow_any)
3479 }
3480 } else {
3481 ctx.add_quick_xml_deserialize_usings(
3482 true,
3483 ["::xsd_parser_types::quick_xml::Deserializer"],
3484 );
3485
3486 quote! {
3487 <#target_type as #with_deserializer>::init(helper, event)
3488 }
3489 };
3490
3491 self.deserializer_enum_variant_fn_next(ctx, &deserializer_matcher, &event_matcher, &output)
3492 }
3493
3494 fn deserializer_enum_variant_fn_next(
3495 &self,
3496 ctx: &Context<'_, '_>,
3497 deserializer_matcher: &TokenStream,
3498 event_matcher: &TokenStream,
3499 output: &TokenStream,
3500 ) -> TokenStream {
3501 let variant_ident = &self.variant_ident;
3502 let handler_ident = self.handler_ident();
3503
3504 let element_handler_output =
3505 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ElementHandlerOutput");
3506
3507 quote! {
3508 (S::#variant_ident(values, fallback, #deserializer_matcher), #event_matcher) => {
3509 let output = #output?;
3510
3511 match self.#handler_ident(helper, values, fallback, output)? {
3512 #element_handler_output::Break { event, allow_any } => break (event, allow_any),
3513 #element_handler_output::Continue { event, .. } => event,
3514 }
3515 },
3516 }
3517 }
3518
3519 fn deserializer_struct_field_decl(&self, ctx: &Context<'_, '_>) -> TokenStream {
3520 let field_ident = &self.field_ident;
3521
3522 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
3523 let target_type = match self.occurs {
3524 Occurs::Single | Occurs::Optional => {
3525 let option = resolve_build_in!(ctx, "::core::option::Option");
3526
3527 quote!(#option<#target_type>)
3528 }
3529 Occurs::StaticList(_) if self.need_indirection => {
3530 let vec = resolve_build_in!(ctx, "::alloc::vec::Vec");
3531 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
3532
3533 quote!(#vec<#box_<#target_type>>)
3534 }
3535 Occurs::StaticList(_) | Occurs::DynamicList => {
3536 let vec = resolve_build_in!(ctx, "::alloc::vec::Vec");
3537
3538 quote!(#vec<#target_type>)
3539 }
3540 e => crate::unreachable!("{:?}", e),
3541 };
3542
3543 quote! {
3544 #field_ident: #target_type,
3545 }
3546 }
3547
3548 fn deserializer_struct_field_init(&self, ctx: &Context<'_, '_>) -> TokenStream {
3549 let occurs = self.occurs;
3550 let field_ident = &self.field_ident;
3551
3552 match occurs {
3553 Occurs::None => quote!(),
3554 Occurs::Single | Occurs::Optional => quote!(#field_ident: None,),
3555 Occurs::DynamicList | Occurs::StaticList(_) => {
3556 let vec = resolve_build_in!(ctx, "::alloc::vec::Vec");
3557
3558 quote!(#field_ident: #vec::new(),)
3559 }
3560 }
3561 }
3562
3563 fn deserializer_struct_field_init_element(&self, ctx: &Context<'_, '_>) -> Option<TokenStream> {
3564 let handler_ident = self.handler_ident();
3565 let call_handler = quote!(self.#handler_ident(helper, output, &mut *fallback));
3566
3567 self.deserializer_init_element(ctx, &call_handler)
3568 }
3569
3570 fn deserializer_struct_field_init_group(
3571 &self,
3572 ctx: &Context<'_, '_>,
3573 handle_any: bool,
3574 ) -> Option<TokenStream> {
3575 if !self.treat_as_group_or_dynamic() {
3576 return None;
3577 }
3578
3579 let handler_ident = self.handler_ident();
3580 let call_handler = quote!(self.#handler_ident(helper, output, &mut *fallback));
3581
3582 Some(self.deserializer_init_group(ctx, handle_any, &call_handler))
3583 }
3584
3585 fn deserializer_struct_field_init_text(&self, ctx: &Context<'_, '_>) -> Option<TokenStream> {
3586 if !self.treat_as_text() {
3587 return None;
3588 }
3589
3590 let handler_ident = self.handler_ident();
3591 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
3592
3593 let with_deserializer =
3594 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::WithDeserializer");
3595
3596 ctx.add_quick_xml_deserialize_usings(true, ["::xsd_parser_types::quick_xml::Deserializer"]);
3597
3598 Some(quote! {
3599 let output = <#target_type as #with_deserializer>::init(helper, event)?;
3600
3601 self.#handler_ident(helper, output, &mut *fallback)
3602 })
3603 }
3604
3605 fn deserializer_struct_field_finish_state_all(&self) -> TokenStream {
3606 let store_ident = self.store_ident();
3607 let variant_ident = &self.variant_ident;
3608
3609 quote! {
3610 S::#variant_ident(deserializer) => self.#store_ident(deserializer.finish(helper)?)?,
3611 }
3612 }
3613
3614 fn deserializer_struct_field_finish_state_sequence(&self) -> TokenStream {
3615 let store_ident = self.store_ident();
3616 let variant_ident = &self.variant_ident;
3617
3618 quote! {
3619 S::#variant_ident(Some(deserializer)) => self.#store_ident(deserializer.finish(helper)?)?,
3620 }
3621 }
3622
3623 fn deserializer_struct_field_finish(&self, ctx: &mut Context<'_, '_>) -> TokenStream {
3624 let name = &self.s_name;
3625 let field_ident = &self.field_ident;
3626
3627 let convert = match self.occurs {
3628 Occurs::None => crate::unreachable!(),
3629 Occurs::Single => {
3630 let value = if ctx.is_defaultable_element(self.meta()) {
3631 quote!(helper.finish_default(self.#field_ident)?)
3632 } else {
3633 quote!(helper.finish_element(#name, self.#field_ident)?)
3634 };
3635
3636 ctx.do_box(self.need_indirection, value)
3637 }
3638 Occurs::Optional if self.need_indirection => {
3639 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
3640
3641 quote! { self.#field_ident.map(#box_::new) }
3642 }
3643 Occurs::Optional => {
3644 quote! { self.#field_ident }
3645 }
3646 Occurs::DynamicList => {
3647 let min = self.meta().min_occurs;
3648 let max = self.meta().max_occurs.render_opt();
3649
3650 if min == 0 {
3651 quote!(self.#field_ident)
3652 } else if ctx.is_defaultable_element(self.meta()) {
3653 quote!(helper.finish_vec_default(#min, self.#field_ident)?)
3654 } else {
3655 quote!(helper.finish_vec(#min, #max, self.#field_ident)?)
3656 }
3657 }
3658 Occurs::StaticList(sz) => {
3659 let value = if ctx.is_defaultable_element(self.meta()) {
3660 quote!(helper.finish_arr_default::<_, #sz>(self.#field_ident)?)
3661 } else {
3662 quote!(helper.finish_arr::<_, #sz>(self.#field_ident)?)
3663 };
3664
3665 ctx.do_box(self.need_indirection, value)
3666 }
3667 };
3668
3669 quote! {
3670 #field_ident: #convert,
3671 }
3672 }
3673
3674 fn deserializer_struct_field_fn_store(&self, ctx: &Context<'_, '_>) -> TokenStream {
3675 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
3676
3677 let name = &self.b_name;
3678 let field_ident = &self.field_ident;
3679 let store_ident = self.store_ident();
3680
3681 let body = match self.occurs {
3682 Occurs::None => crate::unreachable!(),
3683 Occurs::Single | Occurs::Optional => {
3684 let error_kind =
3685 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ErrorKind");
3686 let raw_byte_str =
3687 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::RawByteStr");
3688
3689 quote! {
3690 if self.#field_ident.is_some() {
3691 Err(#error_kind::DuplicateElement(#raw_byte_str::from_slice(#name)))?;
3692 }
3693
3694 self.#field_ident = Some(value);
3695 }
3696 }
3697 Occurs::StaticList(_) if self.need_indirection => {
3698 let box_ = resolve_build_in!(ctx, "::alloc::boxed::Box");
3699
3700 quote! {
3701 self.#field_ident.push(#box_::new(value));
3702 }
3703 }
3704 Occurs::DynamicList | Occurs::StaticList(_) => quote! {
3705 self.#field_ident.push(value);
3706 },
3707 };
3708
3709 let result = resolve_build_in!(ctx, "::core::result::Result");
3710
3711 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
3712
3713 quote! {
3714 fn #store_ident(&mut self, value: #target_type) -> #result<(), #error> {
3715 #body
3716
3717 Ok(())
3718 }
3719 }
3720 }
3721
3722 fn deserializer_struct_field_fn_handle_all(
3723 &self,
3724 ctx: &Context<'_, '_>,
3725 deserializer_state_ident: &Ident2,
3726 ) -> TokenStream {
3727 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
3728
3729 let store_ident = self.store_ident();
3730 let handler_ident = self.handler_ident();
3731 let variant_ident = &self.variant_ident;
3732
3733 let result = resolve_build_in!(ctx, "::core::result::Result");
3734 let option = resolve_build_in!(ctx, "::core::option::Option");
3735
3736 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
3737 let deserialize_helper =
3738 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
3739 let deserializer_output =
3740 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerOutput");
3741 let deserializer_artifact =
3742 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerArtifact");
3743 let element_handler_output =
3744 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ElementHandlerOutput");
3745
3746 #[allow(clippy::if_same_then_else)]
3747 let continue_or_return = if self.treat_as_text() {
3748 quote!(from_event)
3749 } else if self.treat_as_group() {
3750 quote!(from_event)
3751 } else {
3752 quote!(return_to_root)
3753 };
3754
3755 quote! {
3756 fn #handler_ident<'de>(
3757 &mut self,
3758 helper: &mut #deserialize_helper,
3759 output: #deserializer_output<'de, #target_type>,
3760 fallback: &mut #option<#deserializer_state_ident>,
3761 ) -> #result<#element_handler_output<'de>, #error> {
3762 use #deserializer_state_ident as S;
3763
3764 let #deserializer_output {
3765 artifact,
3766 event,
3767 allow_any,
3768 } = output;
3769
3770 if artifact.is_none() {
3771 *self.state__ = S::Next__;
3772
3773 return Ok(#element_handler_output::#continue_or_return(event, allow_any));
3774 }
3775
3776 if let Some(fallback) = fallback.take() {
3777 self.finish_state(helper, fallback)?;
3778 }
3779
3780 match artifact {
3781 #deserializer_artifact::None => unreachable!(),
3782 #deserializer_artifact::Data(data) => {
3783 self.#store_ident(data)?;
3784
3785 *self.state__ = S::Next__;
3786
3787 Ok(#element_handler_output::from_event(event, allow_any))
3788 }
3789 #deserializer_artifact::Deserializer(deserializer) => {
3790 fallback.get_or_insert(S::#variant_ident(deserializer));
3791
3792 *self.state__ = S::Next__;
3793
3794 Ok(#element_handler_output::from_event(event, allow_any))
3795 }
3796 }
3797 }
3798 }
3799 }
3800
3801 #[allow(clippy::too_many_lines)]
3802 fn deserializer_struct_field_fn_handle_sequence(
3803 &self,
3804 ctx: &mut Context<'_, '_>,
3805 next: Option<&ComplexDataElement<'_>>,
3806 deserializer_state_ident: &Ident2,
3807 ) -> TokenStream {
3808 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
3809
3810 let store_ident = self.store_ident();
3811 let field_ident = &self.field_ident;
3812 let variant_ident = &self.variant_ident;
3813 let handler_ident = self.handler_ident();
3814
3815 let result = resolve_build_in!(ctx, "::core::result::Result");
3816 let option = resolve_build_in!(ctx, "::core::option::Option");
3817
3818 let error = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Error");
3819 let deserialize_helper =
3820 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializeHelper");
3821 let deserializer_output =
3822 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerOutput");
3823 let deserializer_artifact =
3824 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::DeserializerArtifact");
3825 let element_handler_output =
3826 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ElementHandlerOutput");
3827
3828 let next_state = if let Some(next) = next {
3829 let variant_ident = &next.variant_ident;
3830
3831 quote!(S::#variant_ident(None))
3832 } else {
3833 quote!(S::Done__)
3834 };
3835
3836 let is_defaultable = ctx.is_defaultable_element(self.meta());
3839 let handler_none = match (is_defaultable, self.occurs, self.meta().min_occurs) {
3840 (_, Occurs::None, _) => unreachable!(),
3841 (_, _, 0) | (_, Occurs::Optional, _) => quote! {
3843 fallback.get_or_insert(S::#variant_ident(None));
3844
3845 *self.state__ = #next_state;
3846
3847 return Ok(#element_handler_output::from_event(event, allow_any));
3848 },
3849 (false, Occurs::Single, _) => quote! {
3852 fallback.get_or_insert(S::#variant_ident(None));
3853
3854 if matches!(&fallback, Some(S::Init__)) {
3855 return Ok(#element_handler_output::break_(event, allow_any));
3856 } else {
3857 return Ok(#element_handler_output::return_to_root(event, allow_any));
3858 }
3859 },
3860 (false, Occurs::DynamicList | Occurs::StaticList(_), min) => quote! {
3863 if matches!(&fallback, Some(S::Init__)) {
3864 return Ok(#element_handler_output::break_(event, allow_any));
3865 } else if self.#field_ident.len() < #min {
3866 fallback.get_or_insert(S::#variant_ident(None));
3867
3868 return Ok(#element_handler_output::return_to_root(event, allow_any));
3869 } else {
3870 fallback.get_or_insert(S::#variant_ident(None));
3871
3872 *self.state__ = #next_state;
3873
3874 return Ok(#element_handler_output::from_event(event, allow_any));
3875 }
3876 },
3877 (true, _, _) => quote! {
3879 fallback.get_or_insert(S::#variant_ident(None));
3880
3881 *self.state__ = #next_state;
3882
3883 return Ok(#element_handler_output::from_event(event, allow_any));
3884 },
3885 };
3886
3887 let data_handler = match (self.occurs, self.meta().max_occurs) {
3889 (Occurs::None, _) => unreachable!(),
3890 (Occurs::Single | Occurs::Optional, _) => quote! {
3892 *self.state__ = #next_state;
3893 },
3894 (Occurs::DynamicList | Occurs::StaticList(_), MaxOccurs::Bounded(max)) => quote! {
3897 if self.#field_ident.len() < #max {
3898 *self.state__ = S::#variant_ident(None);
3899 } else {
3900 *self.state__ = #next_state;
3901 }
3902 },
3903 (_, _) => quote! {
3905 *self.state__ = S::#variant_ident(None);
3906 },
3907 };
3908
3909 let deserializer_handler = match (self.occurs, self.meta().max_occurs) {
3911 (Occurs::Single | Occurs::Optional, _) => quote! {
3915 *self.state__ = #next_state;
3916 },
3917 (Occurs::DynamicList | Occurs::StaticList(_), MaxOccurs::Bounded(max)) => {
3922 assert!(max >= 2);
3923 let max_minus_one = max - 1;
3924 quote! {
3925 if self.#field_ident.len() < #max_minus_one {
3926 *self.state__ = S::#variant_ident(None);
3927 } else {
3928 *self.state__ = #next_state;
3929 }
3930 }
3931 }
3932 (_, _) => quote! {
3934 *self.state__ = S::#variant_ident(None);
3935 },
3936 };
3937
3938 quote! {
3939 fn #handler_ident<'de>(
3940 &mut self,
3941 helper: &mut #deserialize_helper,
3942 output: #deserializer_output<'de, #target_type>,
3943 fallback: &mut #option<#deserializer_state_ident>,
3944 ) -> #result<#element_handler_output<'de>, #error> {
3945 use #deserializer_state_ident as S;
3946
3947 let #deserializer_output {
3948 artifact,
3949 event,
3950 allow_any,
3951 } = output;
3952
3953 if artifact.is_none() {
3954 #handler_none
3955 }
3956
3957 if let Some(fallback) = fallback.take() {
3958 self.finish_state(helper, fallback)?;
3959 }
3960
3961 match artifact {
3962 #deserializer_artifact::None => unreachable!(),
3963 #deserializer_artifact::Data(data) => {
3964 self.#store_ident(data)?;
3965
3966 #data_handler
3967
3968 Ok(#element_handler_output::from_event(event, allow_any))
3969 }
3970 #deserializer_artifact::Deserializer(deserializer) => {
3971 fallback.get_or_insert(S::#variant_ident(Some(deserializer)));
3972
3973 #deserializer_handler
3974
3975 Ok(#element_handler_output::from_event(event, allow_any))
3976 }
3977 }
3978 }
3979 }
3980 }
3981
3982 fn deserializer_struct_field_fn_next_all(&self, ctx: &Context<'_, '_>) -> TokenStream {
3983 let variant_ident = &self.variant_ident;
3984 let handler_ident = self.handler_ident();
3985
3986 let element_handler_output =
3987 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ElementHandlerOutput");
3988
3989 quote! {
3990 (
3991 S::#variant_ident(deserializer),
3992 event
3993 ) => {
3994 let output = deserializer.next(helper, event)?;
3995 match self.#handler_ident(helper, output, &mut fallback)? {
3996 #element_handler_output::Continue { event, .. } => event,
3997 #element_handler_output::Break { event, allow_any } => break (event, allow_any),
3998 }
3999 }
4000 }
4001 }
4002
4003 fn deserializer_struct_field_fn_next_sequence_continue(
4004 &self,
4005 ctx: &Context<'_, '_>,
4006 ) -> TokenStream {
4007 let variant_ident = &self.variant_ident;
4008 let handler_ident = self.handler_ident();
4009
4010 let element_handler_output =
4011 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ElementHandlerOutput");
4012
4013 quote! {
4014 (
4015 S::#variant_ident(Some(deserializer)),
4016 event
4017 ) => {
4018 let output = deserializer.next(helper, event)?;
4019 match self.#handler_ident(helper, output, &mut fallback)? {
4020 #element_handler_output::Continue { event, allow_any } => {
4021 allow_any_element = allow_any_element || allow_any;
4022
4023 event
4024 },
4025 #element_handler_output::Break { event, allow_any } => break (event, allow_any),
4026 }
4027 }
4028 }
4029 }
4030
4031 #[allow(clippy::too_many_lines)]
4032 fn deserializer_struct_field_fn_next_sequence_create(
4033 &self,
4034 ctx: &Context<'_, '_>,
4035 next: Option<&ComplexDataElement<'_>>,
4036 allow_any: bool,
4037 ) -> TokenStream {
4038 let name = &self.b_name;
4039 let variant_ident = &self.variant_ident;
4040 let handler_ident = self.handler_ident();
4041 let target_type = ctx.resolve_type_for_deserialize_module(&self.target_type);
4042
4043 let event = resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::Event");
4044 let with_deserializer =
4045 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::WithDeserializer");
4046 let element_handler_output =
4047 resolve_quick_xml_ident!(ctx, "::xsd_parser_types::quick_xml::ElementHandlerOutput");
4048
4049 ctx.add_quick_xml_deserialize_usings(true, ["::xsd_parser_types::quick_xml::Deserializer"]);
4050
4051 let next_state = if let Some(next) = next {
4052 let variant_ident = &next.variant_ident;
4053
4054 quote!(S::#variant_ident(None))
4055 } else {
4056 quote!(S::Done__)
4057 };
4058
4059 let allow_any = allow_any || self.target_type_allows_any(ctx.types.meta.types);
4060
4061 let need_name_matcher = !self.target_is_dynamic
4062 && matches!(
4063 &self.meta().variant,
4064 ElementMetaVariant::Any { .. }
4065 | ElementMetaVariant::Type {
4066 mode: ElementMode::Element,
4067 ..
4068 }
4069 );
4070
4071 let mut body = quote! {
4072 let output = <#target_type as #with_deserializer>::init(helper, event)?;
4073 match self.#handler_ident(helper, output, &mut fallback)? {
4074 #element_handler_output::Continue { event, allow_any } => {
4075 allow_any_element = allow_any_element || allow_any;
4076
4077 event
4078 },
4079 #element_handler_output::Break { event, allow_any } => break (event, allow_any),
4080 }
4081 };
4082
4083 if self.treat_as_any() {
4084 body = quote! {
4085 if is_any_retry {
4086 #body
4087 } else {
4088 any_fallback.get_or_insert(S::#variant_ident(None));
4089
4090 *self.state__ = #next_state;
4091
4092 event
4093 }
4094 };
4095 } else if need_name_matcher {
4096 let ns_name = self
4097 .meta()
4098 .ident
4099 .ns
4100 .as_ref()
4101 .and_then(|ns| ctx.types.meta.types.modules.get(ns))
4102 .map(|module| ctx.resolve_type_for_deserialize_module(&module.make_ns_const()))
4103 .map_or_else(|| quote!(None), |ns_name| quote!(Some(&#ns_name)));
4104
4105 body = quote! {
4106 let output = helper.init_start_tag_deserializer(event, #ns_name, #name, #allow_any)?;
4107 match self.#handler_ident(helper, output, &mut fallback)? {
4108 #element_handler_output::Continue { event, allow_any } => {
4109 allow_any_element = allow_any_element || allow_any;
4110
4111 event
4112 },
4113 #element_handler_output::Break { event, allow_any } => break (event, allow_any),
4114 }
4115 }
4116 }
4117
4118 let filter = self
4119 .treat_as_text()
4120 .not()
4121 .then(|| quote!(@ (#event::Start(_) | #event::Empty(_))));
4122
4123 quote! {
4124 (S::#variant_ident(None), event #filter) => {
4125 #body
4126 }
4127 }
4128 }
4129}
4130
4131impl Context<'_, '_> {
4132 fn do_box(&self, is_boxed: bool, tokens: TokenStream) -> TokenStream {
4133 if is_boxed {
4134 let box_ = self.resolve_build_in("::alloc::boxed::Box");
4135
4136 quote!(#box_::new(#tokens))
4137 } else {
4138 tokens
4139 }
4140 }
4141
4142 fn set_content(&mut self, value: bool) {
4143 self.values.get_or_create::<DefaultableCache>().content = value;
4144 }
4145
4146 fn is_defaultable_type(&mut self) -> bool {
4147 let cache = self.values.get_or_create::<DefaultableCache>();
4148 let content = cache.content;
4149 let defaultable = cache.get_defaultable(self.meta.types.meta.types, self.ident);
4150
4151 matches!(
4152 (content, defaultable),
4153 (true, Defaultable::Complete | Defaultable::Content) | (false, Defaultable::Complete)
4154 )
4155 }
4156
4157 fn has_defaultable_content(&mut self) -> bool {
4158 self.values
4159 .get_or_create::<DefaultableCache>()
4160 .type_has_defaultable_content(self.meta.types.meta.types, self.ident)
4161 }
4162
4163 fn is_defaultable_element(&mut self, el: &ElementMeta) -> bool {
4164 self.values
4165 .get_or_create::<DefaultableCache>()
4166 .is_defaultable_element(self.meta.types.meta.types, el)
4167 }
4168}
4169
4170impl MaxOccurs {
4171 fn render_opt(&self) -> TokenStream {
4172 match self {
4173 Self::Unbounded => quote!(None),
4174 Self::Bounded(sz) => quote!(Some(#sz)),
4175 }
4176 }
4177}
4178
4179fn boxed_deserializer_ident(is_boxed: bool, deserializer_ident: &Ident2) -> Ident2 {
4180 if is_boxed {
4181 deserializer_ident.clone()
4182 } else {
4183 format_ident!("Self")
4184 }
4185}
4186
4187#[derive(Default, Debug)]
4188struct DefaultableCache {
4189 cache: HashMap<Ident, Option<Defaultable>>,
4190 content: bool,
4191}
4192
4193#[derive(Default, Debug, Clone, Copy)]
4194enum Defaultable {
4195 #[default]
4196 None,
4197 Content,
4198 Complete,
4199}
4200
4201impl ValueKey for DefaultableCache {
4202 type Type = Self;
4203}
4204
4205impl DefaultableCache {
4206 fn is_defaultable_type(&mut self, types: &MetaTypes, ident: &Ident) -> bool {
4207 matches!(
4208 self.get_defaultable_impl(types, ident),
4209 Some(Defaultable::Complete)
4210 )
4211 }
4212
4213 fn type_has_defaultable_content(&mut self, types: &MetaTypes, ident: &Ident) -> bool {
4214 matches!(
4215 self.get_defaultable_impl(types, ident),
4216 Some(Defaultable::Complete | Defaultable::Content)
4217 )
4218 }
4219
4220 fn is_defaultable_element(&mut self, types: &MetaTypes, el: &ElementMeta) -> bool {
4221 if let ElementMetaVariant::Type {
4222 type_,
4223 mode: ElementMode::Group,
4224 } = &el.variant
4225 {
4226 self.is_defaultable_type(types, type_)
4227 } else {
4228 false
4229 }
4230 }
4231
4232 fn get_defaultable(&mut self, types: &MetaTypes, ident: &Ident) -> Defaultable {
4233 self.get_defaultable_impl(types, ident).unwrap_or_default()
4234 }
4235
4236 fn get_defaultable_impl(&mut self, types: &MetaTypes, ident: &Ident) -> Option<Defaultable> {
4237 let create = match self.cache.entry(ident.clone()) {
4238 Entry::Vacant(e) => {
4239 e.insert(None);
4240
4241 true
4242 }
4243 Entry::Occupied(_) => false,
4244 };
4245
4246 let new_value = create.then(|| self.make_new_entry(types, ident));
4247
4248 match self.cache.entry(ident.clone()) {
4249 Entry::Occupied(mut e) => {
4250 if let Some(value) = new_value {
4251 e.insert(Some(value));
4252 }
4253
4254 *e.into_mut()
4255 }
4256 Entry::Vacant(_) => unreachable!(),
4257 }
4258 }
4259
4260 fn make_new_entry(&mut self, types: &MetaTypes, ident: &Ident) -> Defaultable {
4261 match types.get_variant(ident) {
4262 None
4263 | Some(
4264 MetaTypeVariant::Union(_)
4265 | MetaTypeVariant::BuildIn(_)
4266 | MetaTypeVariant::Custom(_)
4267 | MetaTypeVariant::Reference(_)
4268 | MetaTypeVariant::Enumeration(_)
4269 | MetaTypeVariant::Dynamic(_)
4270 | MetaTypeVariant::SimpleType(_),
4271 ) => Defaultable::None,
4272 Some(MetaTypeVariant::All(x) | MetaTypeVariant::Sequence(x)) => {
4273 let mut defaultable = Defaultable::Complete;
4274
4275 for el in &*x.elements {
4276 if el.min_occurs > 0 && !self.is_defaultable_element(types, el) {
4277 defaultable = Defaultable::None;
4278 break;
4279 }
4280 }
4281
4282 defaultable
4283 }
4284 Some(MetaTypeVariant::Choice(x)) => {
4285 let defaultable = x.elements.len() == 1
4286 && x.elements[0].min_occurs >= 1
4287 && matches!(
4288 &x.elements[0].variant,
4289 ElementMetaVariant::Type {
4290 mode: ElementMode::Group,
4291 ..
4292 }
4293 );
4294
4295 if defaultable {
4296 Defaultable::Complete
4297 } else {
4298 Defaultable::None
4299 }
4300 }
4301 Some(MetaTypeVariant::ComplexType(x)) => {
4302 let is_defaultable = x
4303 .content
4304 .as_ref()
4305 .is_some_and(|ident| self.is_defaultable_type(types, ident));
4306
4307 if is_defaultable {
4308 Defaultable::Content
4309 } else {
4310 Defaultable::None
4311 }
4312 }
4313 }
4314 }
4315}