1use std::mem::take;
2use std::ops::Deref;
3
4use proc_macro2::{Ident as Ident2, Literal, TokenStream};
5use quote::{format_ident, quote};
6
7use crate::{
8 code::{format_field_ident, format_variant_ident, IdentPath, ModulePath},
9 schema::{xs::Use, MaxOccurs, MinOccurs, NamespaceId},
10 types::{
11 AnyAttributeInfo, AnyInfo, AttributeInfo, BuildInInfo, ComplexInfo, DynamicInfo,
12 ElementInfo, EnumerationInfo, GroupInfo, Ident, ReferenceInfo, Type, TypeVariant, Types,
13 UnionInfo, UnionTypeInfo, VariantInfo,
14 },
15};
16
17use super::{
18 misc::Occurs, BoxFlags, Config, Error, GeneratorFlags, State, TraitInfos, TypeRef, TypedefMode,
19};
20
21#[derive(Debug)]
30pub enum TypeData<'types> {
31 BuildIn(BuildInType<'types>),
33
34 Union(UnionType<'types>),
36
37 Dynamic(DynamicType<'types>),
39
40 Reference(ReferenceType<'types>),
42
43 Enumeration(EnumerationType<'types>),
45
46 Complex(ComplexType<'types>),
49}
50
51impl<'types> TypeData<'types> {
52 pub(super) fn new(
53 ty: &'types Type,
54 ident: &Ident,
55 config: &Config<'types>,
56 state: &mut State<'types>,
57 ) -> Result<Self, Error> {
58 let req = Request::new(ident, config, state);
59
60 Ok(match &ty.variant {
61 TypeVariant::BuildIn(x) => Self::BuildIn(BuildInType::new(x)),
62 TypeVariant::Union(x) => Self::Union(UnionType::new(x, req)?),
63 TypeVariant::Dynamic(x) => Self::Dynamic(DynamicType::new(x, req)?),
64 TypeVariant::Reference(x) => Self::Reference(ReferenceType::new(x, req)?),
65 TypeVariant::Enumeration(x) => Self::Enumeration(EnumerationType::new(x, req)?),
66 TypeVariant::All(x) => Self::Complex(ComplexType::new_all(x, req)?),
67 TypeVariant::Choice(x) => Self::Complex(ComplexType::new_choice(x, req)?),
68 TypeVariant::Sequence(x) => Self::Complex(ComplexType::new_sequence(x, req)?),
69 TypeVariant::ComplexType(x) => Self::Complex(ComplexType::new_complex(x, req)?),
70 })
71 }
72}
73
74#[derive(Debug)]
77pub struct BuildInType<'types> {
78 pub info: &'types BuildInInfo,
80}
81
82impl<'types> BuildInType<'types> {
83 fn new(info: &'types BuildInInfo) -> Self {
84 Self { info }
85 }
86}
87
88#[derive(Debug)]
91pub struct UnionType<'types> {
92 pub info: &'types UnionInfo,
94
95 pub type_ident: Ident2,
97
98 pub variants: Vec<UnionTypeVariant<'types>>,
100
101 pub trait_impls: Vec<TokenStream>,
103}
104
105#[derive(Debug)]
107pub struct UnionTypeVariant<'types> {
108 pub info: &'types UnionTypeInfo,
110
111 pub target_type: IdentPath,
113
114 pub variant_ident: Ident2,
116}
117
118impl<'types> UnionType<'types> {
119 fn new(info: &'types UnionInfo, mut req: Request<'_, 'types>) -> Result<Self, Error> {
120 let type_ident = req.current_type_ref().type_ident.clone();
121 let trait_impls = req.make_trait_impls()?;
122 let variants = info
123 .types
124 .iter()
125 .map(|info| info.make_variant(&mut req))
126 .collect::<Result<_, _>>()?;
127
128 Ok(Self {
129 info,
130 type_ident,
131 variants,
132 trait_impls,
133 })
134 }
135}
136
137impl UnionTypeInfo {
138 fn make_variant<'types>(
139 &'types self,
140 req: &mut Request<'_, 'types>,
141 ) -> Result<UnionTypeVariant<'types>, Error> {
142 let type_ref = req.get_or_create_type_ref(self.type_.clone())?;
143 let target_type = type_ref.to_ident_path();
144 let variant_ident = format_variant_ident(&self.type_.name, self.display_name.as_deref());
145
146 Ok(UnionTypeVariant {
147 info: self,
148 target_type,
149 variant_ident,
150 })
151 }
152}
153
154#[derive(Debug)]
157pub struct DynamicType<'types> {
158 pub info: &'types DynamicInfo,
160
161 pub type_ident: Ident2,
163
164 pub trait_ident: Ident2,
167
168 pub deserializer_ident: Ident2,
170
171 pub sub_traits: Option<Vec<IdentPath>>,
174
175 pub derived_types: Vec<DerivedType>,
177}
178
179#[derive(Debug)]
181pub struct DerivedType {
182 pub ident: Ident,
184
185 pub b_name: Literal,
187
188 pub target_type: IdentPath,
190
191 pub variant_ident: Ident2,
193}
194
195impl<'types> DynamicType<'types> {
196 fn new(info: &'types DynamicInfo, mut req: Request<'_, 'types>) -> Result<Self, Error> {
197 let type_ident = req.current_type_ref().type_ident.clone();
198 let trait_ident = format_ident!("{type_ident}Trait");
199 let ident = req.ident.clone();
200 let sub_traits = req
201 .get_trait_infos()
202 .get(&ident)
203 .map(|info| info.traits_direct.clone())
204 .map(|traits_direct| {
205 traits_direct
206 .iter()
207 .map(|ident| {
208 req.get_or_create_type_ref(ident.clone()).map(|x| {
209 let ident = format_ident!("{}Trait", x.type_ident);
210
211 x.to_ident_path().with_ident(ident)
212 })
213 })
214 .collect::<Result<Vec<_>, _>>()
215 })
216 .transpose()?;
217 let derived_types = info
218 .derived_types
219 .iter()
220 .map(|ident| make_derived_type_data(&mut req, ident))
221 .collect::<Result<Vec<_>, _>>()?;
222
223 let deserializer_ident = format_ident!("{type_ident}Deserializer");
224
225 Ok(Self {
226 info,
227 type_ident,
228 trait_ident,
229 deserializer_ident,
230 sub_traits,
231 derived_types,
232 })
233 }
234}
235
236#[derive(Debug)]
239pub struct ReferenceType<'types> {
240 pub info: &'types ReferenceInfo,
242
243 pub mode: TypedefMode,
245
246 pub occurs: Occurs,
248
249 pub type_ident: Ident2,
251
252 pub target_type: IdentPath,
254
255 pub trait_impls: Vec<TokenStream>,
257}
258
259impl<'types> ReferenceType<'types> {
260 fn new(info: &'types ReferenceInfo, mut req: Request<'_, 'types>) -> Result<Self, Error> {
261 let occurs = Occurs::from_occurs(info.min_occurs, info.max_occurs);
262 let type_ident = req.current_type_ref().type_ident.clone();
263 let target_ref = req.get_or_create_type_ref(info.type_.clone())?;
264 let target_type = target_ref.to_ident_path();
265 let trait_impls = req.make_trait_impls()?;
266
267 let mode = match (req.typedef_mode, occurs) {
268 (TypedefMode::Auto, Occurs::None | Occurs::Single) => TypedefMode::Typedef,
269 (TypedefMode::Auto, _) => TypedefMode::NewType,
270 (mode, _) => mode,
271 };
272
273 Ok(Self {
274 info,
275 mode,
276 occurs,
277 type_ident,
278 target_type,
279 trait_impls,
280 })
281 }
282}
283
284#[derive(Debug)]
287pub struct EnumerationType<'types> {
288 pub info: &'types EnumerationInfo,
290
291 pub type_ident: Ident2,
293
294 pub variants: Vec<EnumerationTypeVariant<'types>>,
296
297 pub trait_impls: Vec<TokenStream>,
299}
300
301#[derive(Debug)]
303pub struct EnumerationTypeVariant<'types> {
304 pub info: &'types VariantInfo,
306
307 pub variant_ident: Ident2,
309
310 pub target_type: Option<IdentPath>,
312}
313
314impl<'types> EnumerationType<'types> {
315 fn new(info: &'types EnumerationInfo, mut req: Request<'_, 'types>) -> Result<Self, Error> {
316 let mut unknown = 0usize;
317 let type_ident = req.current_type_ref().type_ident.clone();
318 let trait_impls = req.make_trait_impls()?;
319
320 let variants = info
321 .variants
322 .iter()
323 .filter_map(|var| var.make_variant(&mut unknown, &mut req))
324 .collect::<Result<Vec<_>, _>>()?;
325
326 Ok(EnumerationType {
327 info,
328 type_ident,
329 variants,
330 trait_impls,
331 })
332 }
333}
334
335impl VariantInfo {
336 fn make_variant<'types>(
337 &'types self,
338 unknown: &mut usize,
339 req: &mut Request<'_, 'types>,
340 ) -> Option<Result<EnumerationTypeVariant<'types>, Error>> {
341 match self.use_ {
342 Use::Prohibited => None,
343 Use::Required | Use::Optional => {
344 let type_ref = if let Some(t) = &self.type_ {
345 match req.get_or_create_type_ref(t.clone()) {
346 Ok(target_ref) => Some(target_ref),
347 Err(error) => return Some(Err(error)),
348 }
349 } else {
350 None
351 };
352
353 let variant_ident = if let Some(display_name) = self.display_name.as_deref() {
354 format_ident!("{display_name}")
355 } else if let (Some(type_ref), true) = (type_ref, self.ident.name.is_generated()) {
356 type_ref.type_ident.clone()
357 } else if self.ident.name.as_str().is_empty() {
358 *unknown += 1;
359
360 format_ident!("Unknown{unknown}")
361 } else {
362 format_variant_ident(&self.ident.name, self.display_name.as_deref())
363 };
364
365 let target_type = type_ref.map(TypeRef::to_ident_path);
366
367 Some(Ok(EnumerationTypeVariant {
368 info: self,
369 variant_ident,
370 target_type,
371 }))
372 }
373 }
374 }
375}
376
377#[derive(Debug)]
394pub enum ComplexType<'types> {
395 Enum {
399 type_: ComplexTypeEnum<'types>,
401
402 content_type: Option<Box<ComplexType<'types>>>,
404 },
405
406 Struct {
410 type_: ComplexTypeStruct<'types>,
412
413 content_type: Option<Box<ComplexType<'types>>>,
415 },
416}
417
418#[derive(Debug)]
421pub struct ComplexTypeBase {
422 pub type_ident: Ident2,
424
425 pub trait_impls: Vec<TokenStream>,
427
428 pub tag_name: Option<String>,
430
431 pub is_complex: bool,
433
434 pub is_dynamic: bool,
436
437 pub serializer_ident: Ident2,
439
440 pub serializer_state_ident: Ident2,
442
443 pub deserializer_ident: Ident2,
445
446 pub deserializer_state_ident: Ident2,
448}
449
450#[derive(Debug)]
454pub struct ComplexTypeEnum<'types> {
455 pub base: ComplexTypeBase,
457
458 pub elements: Vec<ComplexTypeElement<'types>>,
460
461 pub any_element: Option<&'types AnyInfo>,
463
464 pub any_attribute: Option<&'types AnyAttributeInfo>,
466}
467
468#[derive(Debug)]
472pub struct ComplexTypeStruct<'types> {
473 pub base: ComplexTypeBase,
475
476 pub mode: StructMode<'types>,
478
479 pub attributes: Vec<ComplexTypeAttribute<'types>>,
481
482 pub any_attribute: Option<&'types AnyAttributeInfo>,
484}
485
486#[derive(Debug)]
491pub enum StructMode<'types> {
492 Empty {
494 any_element: Option<&'types AnyInfo>,
496 },
497
498 Content {
501 content: ComplexTypeContent,
503 },
504
505 All {
507 elements: Vec<ComplexTypeElement<'types>>,
509
510 any_element: Option<&'types AnyInfo>,
512 },
513
514 Sequence {
516 elements: Vec<ComplexTypeElement<'types>>,
518
519 any_element: Option<&'types AnyInfo>,
521 },
522}
523
524#[derive(Debug)]
528pub struct ComplexTypeContent {
529 pub occurs: Occurs,
531
532 pub is_simple: bool,
535
536 pub min_occurs: MinOccurs,
538
539 pub max_occurs: MaxOccurs,
541
542 pub target_type: IdentPath,
544}
545
546#[derive(Debug)]
550pub struct ComplexTypeElement<'types> {
551 pub info: &'types ElementInfo,
553
554 pub occurs: Occurs,
556
557 pub s_name: String,
559
560 pub b_name: Literal,
562
563 pub tag_name: String,
565
566 pub field_ident: Ident2,
568
569 pub variant_ident: Ident2,
571
572 pub target_type: IdentPath,
574
575 pub need_indirection: bool,
578
579 pub target_is_dynamic: bool,
582}
583
584#[derive(Debug)]
588pub struct ComplexTypeAttribute<'types> {
589 pub info: &'types AttributeInfo,
591
592 pub ident: Ident2,
594
595 pub s_name: String,
597
598 pub b_name: Literal,
600
601 pub tag_name: String,
603
604 pub is_option: bool,
606
607 pub target_type: IdentPath,
609
610 pub default_value: Option<TokenStream>,
612}
613
614#[derive(Debug, Clone)]
615enum TypeMode {
616 All,
617 Choice,
618 Sequence,
619 Simple { target_type: IdentPath },
620}
621
622impl<'types> ComplexType<'types> {
623 fn new_all(info: &'types GroupInfo, req: Request<'_, 'types>) -> Result<Self, Error> {
624 Self::new(
625 req,
626 TypeMode::All,
627 1,
628 MaxOccurs::Bounded(1),
629 &[],
630 None,
631 &info.elements,
632 info.any.as_ref(),
633 )
634 }
635
636 fn new_choice(info: &'types GroupInfo, req: Request<'_, 'types>) -> Result<Self, Error> {
637 Self::new(
638 req,
639 TypeMode::Choice,
640 1,
641 MaxOccurs::Bounded(1),
642 &[],
643 None,
644 &info.elements,
645 info.any.as_ref(),
646 )
647 }
648
649 fn new_sequence(info: &'types GroupInfo, req: Request<'_, 'types>) -> Result<Self, Error> {
650 Self::new(
651 req,
652 TypeMode::Sequence,
653 1,
654 MaxOccurs::Bounded(1),
655 &[],
656 None,
657 &info.elements,
658 info.any.as_ref(),
659 )
660 }
661
662 fn new_complex(info: &'types ComplexInfo, mut req: Request<'_, 'types>) -> Result<Self, Error> {
663 let (type_mode, elements, any_element) = match info.content.as_ref().and_then(|ident| {
664 req.types
665 .get_resolved_type(ident)
666 .map(|ty| (&ty.variant, ident))
667 }) {
668 None => (TypeMode::Sequence, &[][..], None),
669 Some((TypeVariant::All(si), _)) => (TypeMode::All, &si.elements[..], si.any.as_ref()),
670 Some((TypeVariant::Choice(si), _)) => {
671 (TypeMode::Choice, &si.elements[..], si.any.as_ref())
672 }
673 Some((TypeVariant::Sequence(si), _)) => {
674 (TypeMode::Sequence, &si.elements[..], si.any.as_ref())
675 }
676 Some((
677 TypeVariant::BuildIn(_)
678 | TypeVariant::Union(_)
679 | TypeVariant::Enumeration(_)
680 | TypeVariant::Reference(_),
681 ident,
682 )) => {
683 let content_ref = req.get_or_create_type_ref(ident.clone())?;
684 let target_type = content_ref.to_ident_path();
685
686 (TypeMode::Simple { target_type }, &[][..], None)
687 }
688 Some((x, _)) => {
689 let ident = &req.current_type_ref().type_ident;
690
691 tracing::warn!("Complex type has unexpected content: ident={ident}, info={info:#?}, content={x:#?}!");
692
693 (TypeMode::Sequence, &[][..], None)
694 }
695 };
696
697 Self::new(
698 req,
699 type_mode,
700 info.min_occurs,
701 info.max_occurs,
702 &info.attributes,
703 info.any_attribute.as_ref(),
704 elements,
705 any_element,
706 )
707 }
708
709 #[allow(clippy::too_many_arguments)]
710 fn new(
711 req: Request<'_, 'types>,
712 type_mode: TypeMode,
713 min_occurs: MinOccurs,
714 max_occurs: MaxOccurs,
715 attributes: &'types [AttributeInfo],
716 any_attribute: Option<&'types AnyAttributeInfo>,
717 elements: &'types [ElementInfo],
718 any_element: Option<&'types AnyInfo>,
719 ) -> Result<Self, Error> {
720 match type_mode {
721 TypeMode::Simple { target_type } => Self::new_simple(
722 req,
723 target_type,
724 min_occurs,
725 max_occurs,
726 attributes,
727 any_attribute,
728 ),
729 TypeMode::Choice => Self::new_enum(
730 req,
731 min_occurs,
732 max_occurs,
733 attributes,
734 any_attribute,
735 elements,
736 any_element,
737 ),
738 TypeMode::All | TypeMode::Sequence => Self::new_struct(
739 req,
740 &type_mode,
741 min_occurs,
742 max_occurs,
743 attributes,
744 any_attribute,
745 elements,
746 any_element,
747 ),
748 }
749 }
750
751 fn new_simple(
752 mut req: Request<'_, 'types>,
753 target_type: IdentPath,
754 min_occurs: MinOccurs,
755 max_occurs: MaxOccurs,
756 attributes: &'types [AttributeInfo],
757 any_attribute: Option<&'types AnyAttributeInfo>,
758 ) -> Result<Self, Error> {
759 let base = ComplexTypeBase::new(&mut req)?;
760 let occurs = Occurs::from_occurs(min_occurs, max_occurs);
761 let attributes = attributes
762 .iter()
763 .filter_map(|info| ComplexTypeAttribute::new_field(info, &mut req).transpose())
764 .collect::<Result<Vec<_>, _>>()?;
765
766 let content = ComplexTypeContent {
767 occurs,
768 is_simple: true,
769 min_occurs,
770 max_occurs,
771 target_type,
772 };
773 let type_ = ComplexTypeStruct {
774 base,
775
776 mode: StructMode::Content { content },
777
778 attributes,
779 any_attribute,
780 };
781
782 Ok(Self::Struct {
783 type_,
784 content_type: None,
785 })
786 }
787
788 fn new_enum(
789 mut req: Request<'_, 'types>,
790 min_occurs: MinOccurs,
791 max_occurs: MaxOccurs,
792 attributes: &'types [AttributeInfo],
793 any_attribute: Option<&'types AnyAttributeInfo>,
794 elements: &'types [ElementInfo],
795 any_element: Option<&'types AnyInfo>,
796 ) -> Result<Self, Error> {
797 let base = ComplexTypeBase::new(&mut req)?;
798 let occurs = Occurs::from_occurs(min_occurs, max_occurs);
799 let flatten = occurs == Occurs::Single
800 && attributes.is_empty()
801 && req.check_flags(GeneratorFlags::FLATTEN_ENUM_CONTENT);
802
803 let attributes = attributes
804 .iter()
805 .filter_map(|info| ComplexTypeAttribute::new_field(info, &mut req).transpose())
806 .collect::<Result<Vec<_>, _>>()?;
807
808 let mut any_element = any_element;
809 let mut elements = elements
810 .iter()
811 .filter_map(|info| {
812 ComplexTypeElement::new_variant(info, &mut req, occurs.is_direct()).transpose()
813 })
814 .collect::<Result<Vec<_>, _>>()?;
815
816 if flatten {
817 let type_ = ComplexTypeEnum {
818 base,
819 elements,
820 any_element,
821 any_attribute,
822 };
823
824 return Ok(ComplexType::Enum {
825 type_,
826 content_type: None,
827 });
828 }
829
830 let type_ident = &base.type_ident;
831 let content_ident = format_ident!("{type_ident}Content");
832 let has_content = occurs.is_some() && !elements.is_empty();
833
834 let content_type = has_content.then(|| {
835 let type_ = ComplexTypeEnum {
836 base: ComplexTypeBase::new_empty(content_ident.clone()),
837 elements: take(&mut elements),
838 any_element: any_element.take(),
839 any_attribute: None,
840 };
841
842 Box::new(ComplexType::Enum {
843 type_,
844 content_type: None,
845 })
846 });
847
848 let mode = if has_content {
849 let type_ref = req.current_type_ref();
850 let target_type = type_ref.to_ident_path().with_ident(content_ident.clone());
851 let content = ComplexTypeContent {
852 occurs,
853 is_simple: false,
854 min_occurs,
855 max_occurs,
856 target_type,
857 };
858
859 StructMode::Content { content }
860 } else {
861 StructMode::Empty { any_element }
862 };
863
864 let type_ = ComplexTypeStruct {
865 base,
866 mode,
867
868 attributes,
869 any_attribute,
870 };
871
872 Ok(ComplexType::Struct {
873 type_,
874 content_type,
875 })
876 }
877
878 #[allow(clippy::too_many_arguments)]
879 fn new_struct(
880 mut req: Request<'_, 'types>,
881 type_mode: &TypeMode,
882 min_occurs: MinOccurs,
883 max_occurs: MaxOccurs,
884 attributes: &'types [AttributeInfo],
885 any_attribute: Option<&'types AnyAttributeInfo>,
886 elements: &'types [ElementInfo],
887 any_element: Option<&'types AnyInfo>,
888 ) -> Result<Self, Error> {
889 let base = ComplexTypeBase::new(&mut req)?;
890 let occurs = Occurs::from_occurs(min_occurs, max_occurs);
891 let flatten =
892 occurs == Occurs::Single && req.check_flags(GeneratorFlags::FLATTEN_STRUCT_CONTENT);
893
894 let attributes = attributes
895 .iter()
896 .filter_map(|info| ComplexTypeAttribute::new_field(info, &mut req).transpose())
897 .collect::<Result<Vec<_>, _>>()?;
898
899 let elements = elements
900 .iter()
901 .filter_map(|info| {
902 ComplexTypeElement::new_field(info, &mut req, occurs.is_direct()).transpose()
903 })
904 .collect::<Result<Vec<_>, _>>()?;
905
906 if flatten {
907 let mode = match type_mode {
908 _ if elements.is_empty() => StructMode::Empty { any_element },
909 TypeMode::All => StructMode::All {
910 elements,
911 any_element,
912 },
913 TypeMode::Sequence => StructMode::Sequence {
914 elements,
915 any_element,
916 },
917 _ => crate::unreachable!(),
918 };
919
920 let type_ = ComplexTypeStruct {
921 base,
922 mode,
923
924 attributes,
925 any_attribute,
926 };
927
928 return Ok(ComplexType::Struct {
929 type_,
930 content_type: None,
931 });
932 }
933
934 let type_ident = &base.type_ident;
935 let content_ident = format_ident!("{type_ident}Content");
936 let has_content = occurs.is_some() && !elements.is_empty();
937
938 let content_type = has_content.then(|| {
939 let mode = match type_mode {
940 TypeMode::All => StructMode::All {
941 elements,
942 any_element,
943 },
944 TypeMode::Sequence => StructMode::Sequence {
945 elements,
946 any_element,
947 },
948 _ => crate::unreachable!(),
949 };
950
951 let type_ = ComplexTypeStruct {
952 base: ComplexTypeBase::new_empty(content_ident.clone()),
953 mode,
954
955 attributes: Vec::new(),
956 any_attribute: None,
957 };
958
959 Box::new(ComplexType::Struct {
960 type_,
961 content_type: None,
962 })
963 });
964
965 let mode = if has_content {
966 let type_ref = req.current_type_ref();
967 let target_type = type_ref.to_ident_path().with_ident(content_ident.clone());
968 let content = ComplexTypeContent {
969 occurs,
970 is_simple: false,
971 min_occurs,
972 max_occurs,
973 target_type,
974 };
975
976 StructMode::Content { content }
977 } else {
978 StructMode::Empty { any_element }
979 };
980
981 let type_ = ComplexTypeStruct {
982 base,
983 mode,
984
985 attributes,
986 any_attribute,
987 };
988
989 Ok(ComplexType::Struct {
990 type_,
991 content_type,
992 })
993 }
994}
995
996impl ComplexTypeBase {
997 pub(super) fn element_tag(&self) -> Option<&String> {
998 self.is_complex.then_some(self.tag_name.as_ref()).flatten()
999 }
1000
1001 pub(crate) fn represents_element(&self) -> bool {
1002 self.is_complex && self.tag_name.is_some() && !self.is_dynamic
1003 }
1004
1005 fn new(req: &mut Request<'_, '_>) -> Result<Self, Error> {
1006 let type_ref = req.current_type_ref();
1007 let type_ident = type_ref.type_ident.clone();
1008
1009 let mut ret = Self::new_empty(type_ident);
1010 ret.tag_name = Some(make_tag_name(req.types, req.ident));
1011 ret.trait_impls = req.make_trait_impls()?;
1012
1013 if let Some(TypeVariant::ComplexType(ci)) = req.types.get_variant(req.ident) {
1014 ret.is_complex = true;
1015 ret.is_dynamic = ci.is_dynamic;
1016 }
1017
1018 Ok(ret)
1019 }
1020
1021 fn new_empty(type_ident: Ident2) -> Self {
1022 let serializer_ident = format_ident!("{type_ident}Serializer");
1023 let serializer_state_ident = format_ident!("{type_ident}SerializerState");
1024
1025 let deserializer_ident = format_ident!("{type_ident}Deserializer");
1026 let deserializer_state_ident = format_ident!("{type_ident}DeserializerState");
1027
1028 Self {
1029 type_ident,
1030 trait_impls: Vec::new(),
1031
1032 tag_name: None,
1033 is_complex: false,
1034 is_dynamic: false,
1035
1036 serializer_ident,
1037 serializer_state_ident,
1038
1039 deserializer_ident,
1040 deserializer_state_ident,
1041 }
1042 }
1043}
1044
1045impl Deref for ComplexTypeEnum<'_> {
1046 type Target = ComplexTypeBase;
1047
1048 fn deref(&self) -> &Self::Target {
1049 &self.base
1050 }
1051}
1052
1053impl ComplexTypeStruct<'_> {
1054 pub(super) fn is_unit_struct(&self) -> bool {
1055 matches!(&self.mode, StructMode::Empty { .. }) && !self.has_attributes()
1056 }
1057
1058 pub(super) fn has_attributes(&self) -> bool {
1059 !self.attributes.is_empty()
1060 }
1061
1062 pub(super) fn has_content(&self) -> bool {
1063 match &self.mode {
1064 StructMode::All { elements, .. } | StructMode::Sequence { elements, .. } => {
1065 !elements.is_empty()
1066 }
1067 StructMode::Content { .. } => true,
1068 StructMode::Empty { .. } => false,
1069 }
1070 }
1071
1072 pub(super) fn elements(&self) -> &[ComplexTypeElement<'_>] {
1073 if let StructMode::All { elements, .. } | StructMode::Sequence { elements, .. } = &self.mode
1074 {
1075 elements
1076 } else {
1077 &[]
1078 }
1079 }
1080
1081 pub(super) fn any_element(&self) -> Option<&AnyInfo> {
1082 if let StructMode::All { any_element, .. } | StructMode::Sequence { any_element, .. } =
1083 &self.mode
1084 {
1085 *any_element
1086 } else {
1087 None
1088 }
1089 }
1090
1091 pub(super) fn content(&self) -> Option<&ComplexTypeContent> {
1092 if let StructMode::Content { content, .. } = &self.mode {
1093 Some(content)
1094 } else {
1095 None
1096 }
1097 }
1098}
1099
1100impl Deref for ComplexTypeStruct<'_> {
1101 type Target = ComplexTypeBase;
1102
1103 fn deref(&self) -> &Self::Target {
1104 &self.base
1105 }
1106}
1107
1108impl<'types> ComplexTypeElement<'types> {
1109 fn new_variant(
1110 info: &'types ElementInfo,
1111 req: &mut Request<'_, 'types>,
1112 direct_usage: bool,
1113 ) -> Result<Option<Self>, Error> {
1114 let force_box = req.box_flags.intersects(BoxFlags::ENUM_ELEMENTS);
1115
1116 Self::new(info, req, direct_usage, force_box)
1117 }
1118
1119 fn new_field(
1120 info: &'types ElementInfo,
1121 req: &mut Request<'_, 'types>,
1122 direct_usage: bool,
1123 ) -> Result<Option<Self>, Error> {
1124 let force_box = req.box_flags.intersects(BoxFlags::STRUCT_ELEMENTS);
1125
1126 Self::new(info, req, direct_usage, force_box)
1127 }
1128
1129 fn new(
1130 info: &'types ElementInfo,
1131 req: &mut Request<'_, 'types>,
1132 direct_usage: bool,
1133 force_box: bool,
1134 ) -> Result<Option<Self>, Error> {
1135 let occurs = Occurs::from_occurs(info.min_occurs, info.max_occurs);
1136 if occurs == Occurs::None {
1137 return Ok(None);
1138 }
1139
1140 let tag_name = make_tag_name(req.types, &info.ident);
1141 let s_name = info.ident.name.to_string();
1142 let b_name = Literal::byte_string(s_name.as_bytes());
1143 let field_ident = format_field_ident(&info.ident.name, info.display_name.as_deref());
1144 let variant_ident = format_variant_ident(&info.ident.name, info.display_name.as_deref());
1145
1146 let target_ref = req.get_or_create_type_ref(info.type_.clone())?;
1147 let target_type = target_ref.to_ident_path();
1148
1149 let need_box = req.current_type_ref().boxed_elements.contains(&info.ident);
1150 let need_indirection = (direct_usage && need_box) || force_box;
1151 let target_is_dynamic = is_dynamic(&info.type_, req.types);
1152
1153 Ok(Some(Self {
1154 info,
1155 occurs,
1156 s_name,
1157 b_name,
1158 tag_name,
1159 field_ident,
1160 variant_ident,
1161 target_type,
1162 need_indirection,
1163 target_is_dynamic,
1164 }))
1165 }
1166}
1167
1168impl<'types> ComplexTypeAttribute<'types> {
1169 fn new_field(
1170 info: &'types AttributeInfo,
1171 req: &mut Request<'_, 'types>,
1172 ) -> Result<Option<Self>, Error> {
1173 if info.use_ == Use::Prohibited {
1174 return Ok(None);
1175 }
1176
1177 let current_module = req.current_module();
1178 let target_ref = req.get_or_create_type_ref(info.type_.clone())?;
1179 let ident = format_field_ident(&info.ident.name, info.display_name.as_deref());
1180 let target_type = target_ref.to_ident_path();
1181 let s_name = info.ident.name.to_string();
1182 let b_name = Literal::byte_string(s_name.as_bytes());
1183 let tag_name = make_tag_name(req.types, &info.ident);
1184
1185 let default_value = info
1186 .default
1187 .as_ref()
1188 .map(|default| req.get_default(current_module, default, &info.type_))
1189 .transpose()?;
1190 let is_option = matches!((&info.use_, &default_value), (Use::Optional, None));
1191
1192 Ok(Some(Self {
1193 info,
1194 ident,
1195 s_name,
1196 b_name,
1197 tag_name,
1198 is_option,
1199 target_type,
1200 default_value,
1201 }))
1202 }
1203}
1204
1205struct Request<'a, 'types> {
1209 pub ident: &'a Ident,
1210 pub config: &'a Config<'types>,
1211
1212 state: &'a mut State<'types>,
1213}
1214
1215impl<'a, 'types> Request<'a, 'types> {
1216 fn new(ident: &'a Ident, config: &'a Config<'types>, state: &'a mut State<'types>) -> Self {
1217 Self {
1218 ident,
1219 config,
1220 state,
1221 }
1222 }
1223
1224 fn current_module(&self) -> Option<NamespaceId> {
1225 self.check_flags(GeneratorFlags::USE_MODULES)
1226 .then_some(self.ident.ns)
1227 .flatten()
1228 }
1229
1230 fn current_type_ref(&self) -> &TypeRef {
1231 self.state.cache.get(self.ident).unwrap()
1232 }
1233
1234 fn get_trait_infos(&mut self) -> &TraitInfos {
1235 self.state
1236 .trait_infos
1237 .get_or_insert_with(|| TraitInfos::new(self.config.types))
1238 }
1239
1240 fn get_or_create_type_ref(&mut self, ident: Ident) -> Result<&TypeRef, Error> {
1241 self.state.get_or_create_type_ref(self.config, ident)
1242 }
1243
1244 fn make_trait_impls(&mut self) -> Result<Vec<TokenStream>, Error> {
1245 let ident = self.ident.clone();
1246 let current_ns = self.current_module();
1247 let module_path = ModulePath::from_namespace(current_ns, self.types);
1248
1249 self.get_trait_infos()
1250 .get(&ident)
1251 .into_iter()
1252 .flat_map(|info| &info.traits_all)
1253 .cloned()
1254 .collect::<Vec<_>>()
1255 .into_iter()
1256 .map(|ident| {
1257 let type_ref = self.get_or_create_type_ref(ident.clone())?;
1258 let ident = format_ident!("{}Trait", type_ref.type_ident);
1259 let trait_type = type_ref.to_ident_path().with_ident(ident);
1260 let trait_ident = trait_type.relative_to(&module_path);
1261
1262 Ok(trait_ident)
1263 })
1264 .collect::<Result<Vec<_>, _>>()
1265 }
1266
1267 fn get_default(
1268 &mut self,
1269 current_ns: Option<NamespaceId>,
1270 default: &str,
1271 ident: &Ident,
1272 ) -> Result<TokenStream, Error> {
1273 let types = self.types;
1274 let ty = types
1275 .get(ident)
1276 .ok_or_else(|| Error::UnknownType(ident.clone()))?;
1277 let type_ref = self.get_or_create_type_ref(ident.clone())?;
1278
1279 macro_rules! build_in {
1280 ($ty:ty) => {
1281 if let Ok(val) = default.parse::<$ty>() {
1282 return Ok(quote!(#val));
1283 }
1284 };
1285 }
1286
1287 match &ty.variant {
1288 TypeVariant::BuildIn(BuildInInfo::U8) => build_in!(u8),
1289 TypeVariant::BuildIn(BuildInInfo::U16) => build_in!(u16),
1290 TypeVariant::BuildIn(BuildInInfo::U32) => build_in!(u32),
1291 TypeVariant::BuildIn(BuildInInfo::U64) => build_in!(u64),
1292 TypeVariant::BuildIn(BuildInInfo::U128) => build_in!(u128),
1293 TypeVariant::BuildIn(BuildInInfo::Usize) => build_in!(usize),
1294
1295 TypeVariant::BuildIn(BuildInInfo::I8) => build_in!(i8),
1296 TypeVariant::BuildIn(BuildInInfo::I16) => build_in!(i16),
1297 TypeVariant::BuildIn(BuildInInfo::I32) => build_in!(i32),
1298 TypeVariant::BuildIn(BuildInInfo::I64) => build_in!(i64),
1299 TypeVariant::BuildIn(BuildInInfo::I128) => build_in!(i128),
1300 TypeVariant::BuildIn(BuildInInfo::Isize) => build_in!(isize),
1301
1302 TypeVariant::BuildIn(BuildInInfo::F32) => build_in!(f32),
1303 TypeVariant::BuildIn(BuildInInfo::F64) => build_in!(f64),
1304
1305 TypeVariant::BuildIn(BuildInInfo::Bool) => {
1306 match default.to_ascii_lowercase().as_str() {
1307 "true" | "yes" | "1" => return Ok(quote!(true)),
1308 "false" | "no" | "0" => return Ok(quote!(false)),
1309 _ => (),
1310 }
1311 }
1312 TypeVariant::BuildIn(BuildInInfo::String) => {
1313 return Ok(quote!(String::from(#default)));
1314 }
1315 TypeVariant::BuildIn(BuildInInfo::Custom(x)) => {
1316 if let Some(x) = x.default(default) {
1317 return Ok(x);
1318 }
1319 }
1320
1321 TypeVariant::Enumeration(ei) => {
1322 let module_path = ModulePath::from_namespace(current_ns, types);
1323 let target_type = type_ref.to_ident_path().relative_to(&module_path);
1324
1325 for var in &*ei.variants {
1326 if var.type_.is_none() && var.ident.name.as_str() == default {
1327 let variant_ident =
1328 format_variant_ident(&var.ident.name, var.display_name.as_deref());
1329
1330 return Ok(quote!(#target_type :: #variant_ident));
1331 }
1332
1333 if let Some(target_ident) = &var.type_ {
1334 if let Ok(default) = self.get_default(current_ns, default, target_ident) {
1335 let variant_ident = match self.state.cache.get(target_ident) {
1336 Some(type_ref) if var.ident.name.is_generated() => {
1337 type_ref.type_ident.clone()
1338 }
1339 _ => format_variant_ident(
1340 &var.ident.name,
1341 var.display_name.as_deref(),
1342 ),
1343 };
1344
1345 return Ok(quote!(#target_type :: #variant_ident(#default)));
1346 }
1347 }
1348 }
1349 }
1350
1351 TypeVariant::Union(ui) => {
1352 let module_path = ModulePath::from_namespace(current_ns, types);
1353 let target_type = type_ref.to_ident_path().relative_to(&module_path);
1354
1355 for ty in &*ui.types {
1356 if let Ok(code) = self.get_default(current_ns, default, &ty.type_) {
1357 let variant_ident = match self.state.cache.get(&ty.type_) {
1358 Some(type_ref) if ty.type_.name.is_generated() => {
1359 type_ref.type_ident.clone()
1360 }
1361 _ => format_variant_ident(&ty.type_.name, ty.display_name.as_deref()),
1362 };
1363
1364 return Ok(quote! {
1365 #target_type :: #variant_ident ( #code )
1366 });
1367 }
1368 }
1369 }
1370
1371 TypeVariant::Reference(ti) => match Occurs::from_occurs(ti.min_occurs, ti.max_occurs) {
1372 Occurs::Single => return self.get_default(current_ns, default, &ti.type_),
1373 Occurs::DynamicList if default.is_empty() => {
1374 let module_path = ModulePath::from_namespace(current_ns, types);
1375 let target_type = type_ref.to_ident_path().relative_to(&module_path);
1376
1377 return Ok(quote! { #target_type(Vec::new()) });
1378 }
1379 _ => (),
1380 },
1381
1382 _ => (),
1383 }
1384
1385 Err(Error::InvalidDefaultValue(
1386 ident.clone(),
1387 default.to_owned(),
1388 ))
1389 }
1390}
1391
1392impl<'types> Deref for Request<'_, 'types> {
1393 type Target = Config<'types>;
1394
1395 fn deref(&self) -> &Self::Target {
1396 self.config
1397 }
1398}
1399
1400fn is_dynamic(ident: &Ident, types: &Types) -> bool {
1403 let Some(ty) = types.get(ident) else {
1404 return false;
1405 };
1406
1407 match &ty.variant {
1408 TypeVariant::Dynamic(_) => true,
1409 TypeVariant::ComplexType(ci) => ci.is_dynamic,
1410 TypeVariant::Reference(x) if x.is_single() => is_dynamic(&x.type_, types),
1411 _ => false,
1412 }
1413}
1414
1415fn make_tag_name(types: &Types, ident: &Ident) -> String {
1416 let name = ident.name.to_string();
1417
1418 if let Some(module) = ident
1419 .ns
1420 .as_ref()
1421 .and_then(|ns| types.modules.get(ns))
1422 .and_then(|module| module.name.as_ref())
1423 {
1424 format!("{module}:{name}")
1425 } else {
1426 name
1427 }
1428}
1429
1430fn make_derived_type_data<'types>(
1431 req: &mut Request<'_, 'types>,
1432 ident: &'types Ident,
1433) -> Result<DerivedType, Error> {
1434 let s_name = ident.name.to_string();
1435 let b_name = Literal::byte_string(s_name.as_bytes());
1436
1437 let ty = req
1438 .types
1439 .get(ident)
1440 .ok_or_else(|| Error::UnknownType(ident.clone()))?;
1441 let base_ident = if let TypeVariant::Dynamic(di) = &ty.variant {
1442 di.type_.clone()
1443 } else {
1444 None
1445 };
1446 let ident = base_ident.unwrap_or(ident.clone());
1447
1448 let target_ref = req.get_or_create_type_ref(ident.clone())?;
1449 let target_type = target_ref.to_ident_path();
1450 let variant_ident = format_variant_ident(&ident.name, None);
1451
1452 Ok(DerivedType {
1453 ident,
1454 b_name,
1455 target_type,
1456 variant_ident,
1457 })
1458}