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