1use proc_macro2::{Ident as Ident2, Literal, TokenStream};
2use quote::{format_ident, quote};
3
4use crate::config::TypedefMode;
5use crate::models::{
6 code::IdentPath,
7 data::{
8 ComplexBase, ComplexData, ComplexDataContent, ComplexDataElement, ComplexDataEnum,
9 ComplexDataStruct, DataTypeVariant, DynamicData, EnumerationData, EnumerationTypeVariant,
10 Occurs, ReferenceData, SimpleData, UnionData, UnionTypeVariant,
11 },
12 schema::Namespace,
13};
14
15use super::super::super::{
16 context::{Context, ValueKey},
17 MetaData, RenderStep, RenderStepType,
18};
19
20#[derive(Debug, Clone)]
22pub struct QuickXmlSerializeRenderStep {
23 pub with_namespaces: bool,
25
26 pub default_namespace: Option<Namespace>,
28}
29
30struct SerializerConfig;
31
32impl ValueKey for SerializerConfig {
33 type Type = QuickXmlSerializeRenderStep;
34}
35
36impl RenderStep for QuickXmlSerializeRenderStep {
37 fn render_step_type(&self) -> RenderStepType {
38 RenderStepType::ExtraImpls
39 }
40
41 fn initialize(&mut self, meta: &mut MetaData<'_>) {
42 let ident = IdentPath::from_parts(
43 [meta.xsd_parser_crate.clone(), format_ident!("quick_xml")],
44 format_ident!("WithBoxedSerializer"),
45 );
46
47 if !meta.dyn_type_traits.contains(&ident) {
48 meta.dyn_type_traits.push(ident);
49 }
50 }
51
52 fn render_type(&mut self, ctx: &mut Context<'_, '_>) {
53 ctx.set::<SerializerConfig>(self.clone());
54
55 match &ctx.data.variant {
56 DataTypeVariant::BuildIn(_) | DataTypeVariant::Custom(_) => (),
57 DataTypeVariant::Union(x) => x.render_serializer(ctx),
58 DataTypeVariant::Dynamic(x) => x.render_serializer(ctx),
59 DataTypeVariant::Reference(x) => x.render_serializer(ctx),
60 DataTypeVariant::Enumeration(x) => x.render_serializer(ctx),
61 DataTypeVariant::Simple(x) => x.render_serializer(ctx),
62 DataTypeVariant::Complex(x) => x.render_serializer(ctx),
63 }
64
65 ctx.unset::<SerializerConfig>();
66 }
67}
68
69impl UnionData<'_> {
72 pub(crate) fn render_serializer(&self, ctx: &mut Context<'_, '_>) {
73 let Self {
74 type_ident,
75 variants,
76 ..
77 } = self;
78
79 let variants = variants
80 .iter()
81 .map(UnionTypeVariant::render_serializer_variant)
82 .collect::<Vec<_>>();
83
84 ctx.add_usings([
85 "std::borrow::Cow",
86 "xsd_parser::quick_xml::Error",
87 "xsd_parser::quick_xml::SerializeBytes",
88 ]);
89
90 let code = quote! {
91 impl SerializeBytes for #type_ident {
92 fn serialize_bytes(&self) -> Result<Option<Cow<'_, str>>, Error> {
93 match self {
94 #( #variants )*
95 }
96 }
97 }
98 };
99
100 ctx.current_module().append(code);
101 }
102}
103
104impl UnionTypeVariant<'_> {
105 fn render_serializer_variant(&self) -> TokenStream {
106 let Self { variant_ident, .. } = self;
107
108 quote! {
109 Self::#variant_ident(x) => x.serialize_bytes(),
110 }
111 }
112}
113
114impl DynamicData<'_> {
117 pub(crate) fn render_serializer(&self, ctx: &mut Context<'_, '_>) {
118 let Self { type_ident, .. } = self;
119
120 ctx.add_usings([
121 "xsd_parser::quick_xml::Error",
122 "xsd_parser::quick_xml::WithSerializer",
123 "xsd_parser::quick_xml::BoxedSerializer",
124 ]);
125
126 let code = quote! {
127 impl WithSerializer for #type_ident {
128 type Serializer<'x> = BoxedSerializer<'x>;
129
130 fn serializer<'ser>(
131 &'ser self,
132 name: Option<&'ser str>,
133 is_root: bool
134 ) -> Result<Self::Serializer<'ser>, Error> {
135 let _name = name;
136
137 self.0.serializer(None, is_root)
138 }
139 }
140 };
141
142 ctx.current_module().append(code);
143 }
144}
145
146impl ReferenceData<'_> {
149 pub(crate) fn render_serializer(&self, ctx: &mut Context<'_, '_>) {
150 let Self {
151 mode,
152 occurs,
153 type_ident,
154 ..
155 } = self;
156
157 if matches!(mode, TypedefMode::Auto | TypedefMode::Typedef) {
158 return;
159 }
160
161 let body = match occurs {
162 Occurs::None => return,
163 Occurs::Single => {
164 quote! {
165 self.0.serialize_bytes()
166 }
167 }
168 Occurs::Optional => {
169 quote! {
170 if let Some(inner) = &self.0 {
171 Ok(Some(inner.serialize_bytes()?))
172 } else {
173 Ok(None)
174 }
175 }
176 }
177 Occurs::DynamicList | Occurs::StaticList(_) => {
178 quote! {
179 if self.0.is_empty() {
180 return Ok(None);
181 }
182
183 let mut data = String::new();
184 for item in &self.0 {
185 if let Some(bytes) = item.serialize_bytes()? {
186 if !data.is_empty() {
187 data.push(' ');
188 }
189
190 data.push_str(&bytes);
191 }
192 }
193
194 Ok(Some(Cow::Owned(data)))
195 }
196 }
197 };
198
199 ctx.add_usings([
200 "std::borrow::Cow",
201 "xsd_parser::quick_xml::Error",
202 "xsd_parser::quick_xml::SerializeBytes",
203 ]);
204
205 let code = quote! {
206 impl SerializeBytes for #type_ident {
207 fn serialize_bytes(&self) -> Result<Option<Cow<'_, str>>, Error> {
208 #body
209 }
210 }
211 };
212
213 ctx.current_module().append(code);
214 }
215}
216
217impl EnumerationData<'_> {
220 pub(crate) fn render_serializer(&self, ctx: &mut Context<'_, '_>) {
221 let Self {
222 type_ident,
223 variants,
224 ..
225 } = self;
226
227 let variants = variants
228 .iter()
229 .map(EnumerationTypeVariant::render_serializer_variant);
230
231 ctx.add_usings([
232 "std::borrow::Cow",
233 "xsd_parser::quick_xml::Error",
234 "xsd_parser::quick_xml::SerializeBytes",
235 ]);
236
237 let code = quote! {
238 impl SerializeBytes for #type_ident {
239 fn serialize_bytes(&self) -> Result<Option<Cow<'_, str>>, Error> {
240 match self {
241 #( #variants )*
242 }
243 }
244 }
245 };
246
247 ctx.current_module().append(code);
248 }
249}
250
251impl EnumerationTypeVariant<'_> {
252 fn render_serializer_variant(&self) -> TokenStream {
253 let Self {
254 s_name,
255 target_type,
256 variant_ident,
257 ..
258 } = self;
259
260 if target_type.is_some() {
261 quote! {
262 Self::#variant_ident(x) => x.serialize_bytes(),
263 }
264 } else {
265 quote! {
266 Self::#variant_ident => Ok(Some(Cow::Borrowed(#s_name))),
267 }
268 }
269 }
270}
271
272impl SimpleData<'_> {
275 pub(crate) fn render_serializer(&self, ctx: &mut Context<'_, '_>) {
276 let Self { type_ident, .. } = self;
277
278 ctx.add_usings([
279 "std::borrow::Cow",
280 "xsd_parser::quick_xml::Error",
281 "xsd_parser::quick_xml::SerializeBytes",
282 ]);
283
284 let body = if let Some(digits) = self.meta.fraction_digits {
285 let format = format!("{{inner:.0{digits}}}");
286
287 quote! {
288 let Self(inner) = self;
289
290 Ok(Some(Cow::Owned(format!(#format))))
291 }
292 } else if self.meta.is_list {
293 quote! {
294 if self.0.is_empty() {
295 return Ok(None);
296 }
297
298 let mut data = String::new();
299 for item in &self.0 {
300 if let Some(bytes) = item.serialize_bytes()? {
301 if !data.is_empty() {
302 data.push(' ');
303 }
304
305 data.push_str(&bytes);
306 }
307 }
308
309 Ok(Some(Cow::Owned(data)))
310 }
311 } else {
312 quote! {
313 self.0.serialize_bytes()
314 }
315 };
316
317 let code = quote! {
318 impl SerializeBytes for #type_ident {
319 fn serialize_bytes(&self) -> Result<Option<Cow<'_, str>>, Error> {
320 #body
321 }
322 }
323 };
324
325 ctx.current_module().append(code);
326 }
327}
328
329impl ComplexData<'_> {
332 pub(crate) fn render_serializer(&self, ctx: &mut Context<'_, '_>) {
333 match self {
334 Self::Enum {
335 type_,
336 content_type,
337 } => {
338 type_.render_serializer(ctx);
339
340 if let Some(content_type) = content_type {
341 content_type.render_serializer(ctx);
342 }
343 }
344 Self::Struct {
345 type_,
346 content_type,
347 } => {
348 type_.render_serializer(ctx);
349
350 if let Some(content_type) = content_type {
351 content_type.render_serializer(ctx);
352 }
353 }
354 }
355 }
356}
357
358impl ComplexBase<'_> {
359 fn render_with_serializer(&self, ctx: &mut Context<'_, '_>, forward_root: bool) {
360 let Self {
361 type_ident,
362 serializer_ident,
363 ..
364 } = self;
365
366 let body = if let Some(tag_name) = &self.element_tag() {
367 let config = ctx.get_ref::<SerializerConfig>();
368 let tag_name = tag_name.get_for_default_namespace(&config.default_namespace);
369
370 self.render_with_serializer_for_element(&tag_name)
371 } else {
372 self.render_with_serializer_for_content(forward_root)
373 };
374
375 ctx.add_usings([
376 "xsd_parser::quick_xml::Error",
377 "xsd_parser::quick_xml::WithSerializer",
378 ]);
379
380 let code = quote! {
381 impl WithSerializer for #type_ident {
382 type Serializer<'x> = quick_xml_serialize::#serializer_ident<'x>;
383
384 fn serializer<'ser>(
385 &'ser self,
386 name: Option<&'ser str>,
387 is_root: bool
388 ) -> Result<Self::Serializer<'ser>, Error> {
389 #body
390 }
391 }
392 };
393
394 ctx.current_module().append(code);
395 }
396
397 fn render_with_serializer_for_element(&self, tag_name: &str) -> TokenStream {
398 let Self {
399 serializer_ident,
400 serializer_state_ident,
401 ..
402 } = self;
403
404 quote! {
405 Ok(quick_xml_serialize::#serializer_ident {
406 value: self,
407 state: Box::new(quick_xml_serialize::#serializer_state_ident::Init__),
408 name: name.unwrap_or(#tag_name),
409 is_root,
410 })
411 }
412 }
413
414 fn render_with_serializer_for_content(&self, forward_root: bool) -> TokenStream {
415 let Self {
416 serializer_ident,
417 serializer_state_ident,
418 ..
419 } = self;
420
421 let drop_root = (!forward_root).then(|| quote!(let _is_root = is_root;));
422 let forward_root = forward_root.then(|| quote!(is_root,));
423
424 quote! {
425 let _name = name;
426 #drop_root
427
428 Ok(quick_xml_serialize::#serializer_ident {
429 value: self,
430 state: Box::new(quick_xml_serialize::#serializer_state_ident::Init__),
431 #forward_root
432 })
433 }
434 }
435
436 fn render_serializer_type(&self, ctx: &mut Context<'_, '_>, forward_root: bool) {
437 let Self {
438 type_ident,
439 serializer_ident,
440 serializer_state_ident,
441 ..
442 } = self;
443
444 let name = self.represents_element().then(|| {
445 quote! {
446 pub(super) name: &'ser str,
447 }
448 });
449 let is_root = forward_root.then(|| {
450 quote! {
451 pub(super) is_root: bool,
452 }
453 });
454
455 let code = quote! {
456 #[derive(Debug)]
457 pub struct #serializer_ident<'ser> {
458 pub(super) value: &'ser super::#type_ident,
459 pub(super) state: Box<#serializer_state_ident<'ser>>,
460 #name
461 #is_root
462 }
463 };
464
465 ctx.quick_xml_serialize().append(code);
466 }
467
468 fn render_serializer_handle_state_end(&self, ctx: &Context<'_, '_>) -> TokenStream {
469 let serializer_state_ident = &self.serializer_state_ident;
470
471 ctx.add_quick_xml_serialize_usings(["xsd_parser::quick_xml::BytesEnd"]);
472
473 quote! {
474 #serializer_state_ident::End__ => {
475 *self.state = #serializer_state_ident::Done__;
476
477 return Ok(Some(
478 Event::End(
479 BytesEnd::new(self.name))
480 )
481 );
482 }
483 }
484 }
485
486 fn render_serializer_xmlns(&self, ctx: &Context<'_, '_>) -> Vec<TokenStream> {
487 let _self = self;
488
489 let config = ctx.get_ref::<SerializerConfig>();
490 if !config.with_namespaces {
491 return Vec::new();
492 }
493
494 ctx.types
495 .meta
496 .types
497 .modules
498 .values()
499 .filter_map(|module| {
500 let ns = module.namespace.as_ref()?;
501 if *ns == Namespace::XS || *ns == Namespace::XML {
502 return None;
503 }
504
505 let ns_const = ctx.resolve_type_for_serialize_module(&module.make_ns_const());
506
507 let buffer;
508 let xmlns = if let Some(prefix) = &module.prefix {
509 if matches!((&config.default_namespace, &module.namespace), (a, b) if a == b) {
510 b"xmlns"
511 } else {
512 buffer = format!("xmlns:{prefix}");
513 buffer.as_bytes()
514 }
515 } else {
516 b"xmlns"
517 };
518 let xmlns = Literal::byte_string(xmlns);
519
520 Some(quote! {
521 bytes.push_attribute((&#xmlns[..], &#ns_const[..]));
522 })
523 })
524 .collect::<Vec<_>>()
525 }
526}
527
528impl ComplexDataEnum<'_> {
529 fn serializer_need_end_state(&self) -> bool {
530 self.represents_element()
531 }
532
533 fn render_serializer(&self, ctx: &mut Context<'_, '_>) {
534 self.render_with_serializer(ctx, !self.is_content);
535 self.render_serializer_type(ctx, !self.is_content);
536 self.render_serializer_state_type(ctx);
537 self.render_serializer_impl(ctx);
538 }
539
540 fn render_serializer_state_type(&self, ctx: &mut Context<'_, '_>) {
541 let serializer_state_ident = &self.serializer_state_ident;
542
543 let state_variants = self
544 .elements
545 .iter()
546 .map(|x| x.render_serializer_state_variant(ctx));
547 let state_end = self.represents_element().then(|| {
548 quote! {
549 End__,
550 }
551 });
552
553 let code = quote! {
554 #[derive(Debug)]
555 pub(super) enum #serializer_state_ident<'ser> {
556 Init__,
557 #( #state_variants )*
558 #state_end
559 Done__,
560 Phantom__(&'ser ()),
561 }
562 };
563
564 ctx.quick_xml_serialize().append(code);
565 }
566
567 fn render_serializer_impl(&self, ctx: &mut Context<'_, '_>) {
568 let serializer_ident = &self.serializer_ident;
569 let serializer_state_ident = &self.serializer_state_ident;
570
571 let emit_start_event = self
572 .serializer_need_end_state()
573 .then(|| self.render_serializer_impl_start_event(ctx));
574
575 let final_state = if self.serializer_need_end_state() {
576 quote!(#serializer_state_ident::End__)
577 } else {
578 quote!(#serializer_state_ident::Done__)
579 };
580
581 let variants_init = self.elements.iter().map(|element| {
582 let type_ident = &self.type_ident;
583 let variant_ident = &element.variant_ident;
584 let init = element.render_serializer_enum_state_init(
585 ctx,
586 &self.serializer_state_ident,
587 !self.is_content,
588 );
589
590 quote! {
591 super::#type_ident::#variant_ident(x) => #init,
592 }
593 });
594
595 let handle_state_init = quote! {
596 match self.value {
597 #( #variants_init )*
598 }
599 };
600
601 let handle_state_variants = self.elements.iter().map(|element| {
602 let variant_ident = &element.variant_ident;
603
604 quote! {
605 #serializer_state_ident::#variant_ident(x) => {
606 match x.next().transpose()? {
607 Some(event) => return Ok(Some(event)),
608 None => *self.state = #final_state,
609 }
610 }
611 }
612 });
613
614 let handle_state_end = self
615 .serializer_need_end_state()
616 .then(|| self.render_serializer_handle_state_end(ctx));
617
618 ctx.add_quick_xml_serialize_usings([
619 "core::iter::Iterator",
620 "xsd_parser::quick_xml::Event",
621 "xsd_parser::quick_xml::Error",
622 ]);
623
624 let code = quote! {
625 impl<'ser> #serializer_ident<'ser> {
626 fn next_event(&mut self) -> Result<Option<Event<'ser>>, Error> {
627 loop {
628 match &mut *self.state {
629 #serializer_state_ident::Init__ => {
630 #handle_state_init
631 #emit_start_event
632 }
633 #( #handle_state_variants )*
634 #handle_state_end
635 #serializer_state_ident::Done__ => return Ok(None),
636 #serializer_state_ident::Phantom__(_) => unreachable!(),
637 }
638 }
639 }
640 }
641
642 impl<'ser> Iterator for #serializer_ident<'ser> {
643 type Item = Result<Event<'ser>, Error>;
644
645 fn next(&mut self) -> Option<Self::Item> {
646 match self.next_event() {
647 Ok(Some(event)) => Some(Ok(event)),
648 Ok(None) => None,
649 Err(error) => {
650 *self.state = #serializer_state_ident::Done__;
651
652 Some(Err(error))
653 }
654 }
655 }
656 }
657 };
658
659 ctx.quick_xml_serialize().append(code);
660 }
661
662 fn render_serializer_impl_start_event(&self, ctx: &Context<'_, '_>) -> TokenStream {
663 ctx.add_quick_xml_serialize_usings(["xsd_parser::quick_xml::BytesStart"]);
664
665 let xmlns = self.render_serializer_xmlns(ctx);
666 let bytes_ctor = if xmlns.is_empty() {
667 quote! {
668 let bytes = BytesStart::new(self.name);
669 }
670 } else {
671 quote! {
672 let mut bytes = BytesStart::new(self.name);
673 if self.is_root {
674 #( #xmlns )*
675 }
676 }
677 };
678
679 quote! {
680 #bytes_ctor
681 return Ok(Some(Event::Start(bytes)))
682 }
683 }
684}
685
686impl ComplexDataStruct<'_> {
687 fn serializer_need_end_state(&self) -> bool {
688 self.represents_element() && self.has_content()
689 }
690
691 fn render_serializer(&self, ctx: &mut Context<'_, '_>) {
692 self.render_with_serializer(ctx, self.represents_element());
693 self.render_serializer_type(ctx, self.represents_element());
694 self.render_serializer_state_type(ctx);
695 self.render_serializer_impl(ctx);
696 }
697
698 fn render_serializer_state_type(&self, ctx: &mut Context<'_, '_>) {
699 let state_ident = &self.serializer_state_ident;
700
701 let state_variants = self
702 .elements()
703 .iter()
704 .map(|x| x.render_serializer_state_variant(ctx));
705 let state_content = self
706 .content()
707 .and_then(|x| x.render_serializer_state_variant(ctx));
708 let state_end = self.serializer_need_end_state().then(|| {
709 quote! {
710 End__,
711 }
712 });
713
714 let code = quote! {
715 #[derive(Debug)]
716 pub(super) enum #state_ident<'ser> {
717 Init__,
718 #( #state_variants )*
719 #state_content
720 #state_end
721 Done__,
722 Phantom__(&'ser ()),
723 }
724 };
725
726 ctx.quick_xml_serialize().append(code);
727 }
728
729 #[allow(clippy::too_many_lines)]
730 fn render_serializer_impl(&self, ctx: &mut Context<'_, '_>) {
731 let serializer_ident = &self.serializer_ident;
732 let serializer_state_ident = &self.serializer_state_ident;
733
734 let emit_start_event = self
735 .represents_element()
736 .then(|| self.render_serializer_impl_start_event(ctx));
737
738 let final_state = if self.serializer_need_end_state() {
739 quote!(#serializer_state_ident::End__)
740 } else {
741 quote!(#serializer_state_ident::Done__)
742 };
743
744 let elements = self.elements();
745 let handle_state_init = if let Some(first) = elements.first() {
746 let init = first.render_serializer_struct_state_init(ctx, serializer_state_ident);
747
748 quote!(#init;)
749 } else if let Some(content) = &self.content() {
750 let init = content.render_serializer_state_init(ctx, serializer_state_ident);
751
752 quote!(#init;)
753 } else {
754 quote!(*self.state = #final_state;)
755 };
756
757 let handle_state_variants = (0..).take(elements.len()).map(|i| {
758 let element = &elements[i];
759 let variant_ident = &element.variant_ident;
760
761 let next = if let Some(next) = elements.get(i + 1) {
762 let init = next.render_serializer_struct_state_init(ctx, serializer_state_ident);
763
764 quote!(#init,)
765 } else {
766 quote! {
767 *self.state = #final_state,
768 }
769 };
770
771 quote! {
772 #serializer_state_ident::#variant_ident(x) => match x.next().transpose()? {
773 Some(event) => return Ok(Some(event)),
774 None => #next
775 }
776 }
777 });
778
779 let handle_state_content = self.content().map(|_| {
780 quote! {
781 #serializer_state_ident::Content__(x) => match x.next().transpose()? {
782 Some(event) => return Ok(Some(event)),
783 None => *self.state = #final_state,
784 }
785 }
786 });
787
788 let handle_state_end = self
789 .serializer_need_end_state()
790 .then(|| self.render_serializer_handle_state_end(ctx));
791
792 ctx.add_quick_xml_serialize_usings([
793 "core::iter::Iterator",
794 "xsd_parser::quick_xml::Event",
795 "xsd_parser::quick_xml::Error",
796 ]);
797
798 let code = quote! {
799 impl<'ser> #serializer_ident<'ser> {
800 fn next_event(&mut self) -> Result<Option<Event<'ser>>, Error>
801 {
802 loop {
803 match &mut *self.state {
804 #serializer_state_ident::Init__ => {
805 #handle_state_init
806 #emit_start_event
807 }
808 #( #handle_state_variants )*
809 #handle_state_content
810 #handle_state_end
811 #serializer_state_ident::Done__ => return Ok(None),
812 #serializer_state_ident::Phantom__(_) => unreachable!(),
813 }
814 }
815 }
816 }
817
818 impl<'ser> Iterator for #serializer_ident<'ser> {
819 type Item = Result<Event<'ser>, Error>;
820
821 fn next(&mut self) -> Option<Self::Item> {
822 match self.next_event() {
823 Ok(Some(event)) => Some(Ok(event)),
824 Ok(None) => None,
825 Err(error) => {
826 *self.state = #serializer_state_ident::Done__;
827
828 Some(Err(error))
829 }
830 }
831 }
832 }
833 };
834
835 ctx.quick_xml_serialize().append(code);
836 }
837
838 fn render_serializer_impl_start_event(&self, ctx: &Context<'_, '_>) -> TokenStream {
839 let xmlns = self.render_serializer_xmlns(ctx);
840 let attributes = self.attributes.iter().map(|attrib| {
841 let attrib_name = attrib.tag_name.get(true);
842 let field_ident = &attrib.ident;
843
844 if attrib.meta.is_any() {
845 quote! {
846 bytes.extend_attributes(self.value.#field_ident.attributes());
847 }
848 } else if attrib.is_option {
849 ctx.add_quick_xml_serialize_usings(["xsd_parser::quick_xml::write_attrib_opt"]);
850
851 quote! {
852 write_attrib_opt(&mut bytes, #attrib_name, &self.value.#field_ident)?;
853 }
854 } else {
855 ctx.add_quick_xml_serialize_usings(["xsd_parser::quick_xml::write_attrib"]);
856
857 quote! {
858 write_attrib(&mut bytes, #attrib_name, &self.value.#field_ident)?;
859 }
860 }
861 });
862
863 ctx.add_quick_xml_serialize_usings([
864 "xsd_parser::quick_xml::Event",
865 "xsd_parser::quick_xml::BytesStart",
866 ]);
867
868 let bytes_mut = self.has_attributes().then(|| quote!(mut));
869 let bytes_ctor = if xmlns.is_empty() {
870 quote! {
871 let #bytes_mut bytes = BytesStart::new(self.name);
872 }
873 } else {
874 quote! {
875 let mut bytes = BytesStart::new(self.name);
876 if self.is_root {
877 #( #xmlns )*
878 }
879 }
880 };
881
882 let event = if self.has_content() {
883 format_ident!("Start")
884 } else {
885 format_ident!("Empty")
886 };
887
888 quote! {
889 #bytes_ctor
890 #( #attributes )*
891 return Ok(Some(Event::#event(bytes)))
892 }
893 }
894}
895
896impl ComplexDataContent<'_> {
897 fn render_serializer_state_variant(&self, ctx: &Context<'_, '_>) -> Option<TokenStream> {
898 let serializer = self
899 .occurs
900 .make_serializer_type(&ctx.resolve_type_for_serialize_module(&self.target_type))?;
901
902 Some(quote! {
903 Content__(#serializer),
904 })
905 }
906
907 fn render_serializer_state_init(
908 &self,
909 ctx: &Context<'_, '_>,
910 state_ident: &Ident2,
911 ) -> TokenStream {
912 match self.occurs {
913 Occurs::None => crate::unreachable!(),
914 Occurs::Single => {
915 ctx.add_quick_xml_serialize_usings(["xsd_parser::quick_xml::WithSerializer"]);
916
917 quote! {
918 *self.state = #state_ident::Content__(
919 WithSerializer::serializer(&self.value.content, None, false)?
920 )
921 }
922 }
923 Occurs::Optional => {
924 ctx.add_quick_xml_serialize_usings(["xsd_parser::quick_xml::IterSerializer"]);
925
926 quote! {
927 *self.state = #state_ident::Content__(
928 IterSerializer::new(
929 self.value.content.as_ref(),
930 None,
931 false
932 )
933 )
934 }
935 }
936 Occurs::DynamicList | Occurs::StaticList(_) => {
937 ctx.add_quick_xml_serialize_usings(["xsd_parser::quick_xml::IterSerializer"]);
938
939 quote! {
940 *self.state = #state_ident::Content__(
941 IterSerializer::new(
942 &self.value.content[..],
943 None,
944 false
945 )
946 )
947 }
948 }
949 }
950 }
951}
952
953impl ComplexDataElement<'_> {
954 fn render_serializer_state_variant(&self, ctx: &Context<'_, '_>) -> TokenStream {
955 let target_type = ctx.resolve_type_for_serialize_module(&self.target_type);
956 let variant_ident = &self.variant_ident;
957 let serializer = self.occurs.make_serializer_type(&target_type);
958
959 quote! {
960 #variant_ident(#serializer),
961 }
962 }
963
964 fn render_serializer_enum_state_init(
965 &self,
966 ctx: &Context<'_, '_>,
967 state_ident: &Ident2,
968 forward_root: bool,
969 ) -> TokenStream {
970 let value = match self.occurs {
971 Occurs::None => unreachable!(),
972 Occurs::Single if self.need_indirection => quote!(&**x),
973 Occurs::Single => quote!(x),
974 Occurs::Optional if self.need_indirection => quote!(x.as_ref().map(|x| &**x)),
975 Occurs::Optional => quote!(x.as_ref()),
976 Occurs::DynamicList | Occurs::StaticList(_) => quote!(&x[..]),
977 };
978
979 self.render_serializer_state_init(ctx, state_ident, &value, forward_root)
980 }
981
982 fn render_serializer_struct_state_init(
983 &self,
984 ctx: &Context<'_, '_>,
985 state_ident: &Ident2,
986 ) -> TokenStream {
987 let field_ident = &self.field_ident;
988
989 let value = match self.occurs {
990 Occurs::None => unreachable!(),
991 Occurs::Single if self.need_indirection => quote!(&*self.value.#field_ident),
992 Occurs::Single => quote!(&self.value.#field_ident),
993 Occurs::Optional if self.need_indirection => {
994 quote!(self.value.#field_ident.as_ref().map(|x| &**x))
995 }
996 Occurs::Optional => quote!(self.value.#field_ident.as_ref()),
997 Occurs::DynamicList | Occurs::StaticList(_) => quote!(&self.value.#field_ident[..]),
998 };
999
1000 self.render_serializer_state_init(ctx, state_ident, &value, false)
1001 }
1002
1003 fn render_serializer_state_init(
1004 &self,
1005 ctx: &Context<'_, '_>,
1006 state_ident: &Ident2,
1007 value: &TokenStream,
1008 forward_root: bool,
1009 ) -> TokenStream {
1010 let config = ctx.get_ref::<SerializerConfig>();
1011 let field_name = self
1012 .tag_name
1013 .get_for_default_namespace(&config.default_namespace);
1014 let variant_ident = &self.variant_ident;
1015
1016 let is_root = if forward_root {
1017 quote!(self.is_root)
1018 } else {
1019 quote!(false)
1020 };
1021
1022 match self.occurs {
1023 Occurs::None => crate::unreachable!(),
1024 Occurs::Single => {
1025 ctx.add_quick_xml_serialize_usings(["xsd_parser::quick_xml::WithSerializer"]);
1026
1027 quote! {
1028 *self.state = #state_ident::#variant_ident(
1029 WithSerializer::serializer(#value, Some(#field_name), #is_root)?
1030 )
1031 }
1032 }
1033 Occurs::Optional | Occurs::DynamicList | Occurs::StaticList(_) => {
1034 ctx.add_quick_xml_serialize_usings(["xsd_parser::quick_xml::IterSerializer"]);
1035
1036 quote! {
1037 *self.state = #state_ident::#variant_ident(
1038 IterSerializer::new(
1039 #value,
1040 Some(#field_name),
1041 #is_root
1042 )
1043 )
1044 }
1045 }
1046 }
1047 }
1048}
1049
1050impl Occurs {
1051 fn make_serializer_type(&self, target_type: &TokenStream) -> Option<TokenStream> {
1052 match self {
1053 Occurs::None => None,
1054 Occurs::Single => Some(quote!(<#target_type as WithSerializer>::Serializer<'ser>)),
1055 Occurs::Optional => {
1056 Some(quote!(IterSerializer<'ser, Option<&'ser #target_type>, #target_type>))
1057 }
1058 Occurs::DynamicList | Occurs::StaticList(..) => {
1059 Some(quote!(IterSerializer<'ser, &'ser [#target_type], #target_type>))
1060 }
1061 }
1062 }
1063}