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<IdentPath>,
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<IdentPath>,
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<IdentPath>,
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 self.ident.name.as_str().is_empty() {
356 *unknown += 1;
357
358 format_ident!("Unknown{unknown}")
359 } else {
360 format_variant_ident(&self.ident.name, self.display_name.as_deref())
361 };
362
363 let target_type = type_ref.map(TypeRef::to_ident_path);
364
365 Some(Ok(EnumerationTypeVariant {
366 info: self,
367 variant_ident,
368 target_type,
369 }))
370 }
371 }
372 }
373}
374
375#[derive(Debug)]
392pub enum ComplexType<'types> {
393 Enum {
397 type_: ComplexTypeEnum<'types>,
399
400 content_type: Option<Box<ComplexType<'types>>>,
402 },
403
404 Struct {
408 type_: ComplexTypeStruct<'types>,
410
411 content_type: Option<Box<ComplexType<'types>>>,
413 },
414}
415
416#[derive(Debug)]
419pub struct ComplexTypeBase {
420 pub type_ident: Ident2,
422
423 pub trait_impls: Vec<IdentPath>,
425
426 pub tag_name: Option<String>,
428
429 pub is_complex: bool,
431
432 pub is_dynamic: bool,
434
435 pub serializer_ident: Ident2,
437
438 pub serializer_state_ident: Ident2,
440
441 pub deserializer_ident: Ident2,
443
444 pub deserializer_state_ident: Ident2,
446}
447
448#[derive(Debug)]
452pub struct ComplexTypeEnum<'types> {
453 pub base: ComplexTypeBase,
455
456 pub elements: Vec<ComplexTypeElement<'types>>,
458
459 pub any_element: Option<&'types AnyInfo>,
461
462 pub any_attribute: Option<&'types AnyAttributeInfo>,
464}
465
466#[derive(Debug)]
470pub struct ComplexTypeStruct<'types> {
471 pub base: ComplexTypeBase,
473
474 pub mode: StructMode<'types>,
476
477 pub attributes: Vec<ComplexTypeAttribute<'types>>,
479
480 pub any_attribute: Option<&'types AnyAttributeInfo>,
482}
483
484#[derive(Debug)]
489pub enum StructMode<'types> {
490 Empty {
492 any_element: Option<&'types AnyInfo>,
494 },
495
496 Content {
499 content: ComplexTypeContent,
501 },
502
503 All {
505 elements: Vec<ComplexTypeElement<'types>>,
507
508 any_element: Option<&'types AnyInfo>,
510 },
511
512 Sequence {
514 elements: Vec<ComplexTypeElement<'types>>,
516
517 any_element: Option<&'types AnyInfo>,
519 },
520}
521
522#[derive(Debug)]
526pub struct ComplexTypeContent {
527 pub occurs: Occurs,
529
530 pub is_simple: bool,
533
534 pub min_occurs: MinOccurs,
536
537 pub max_occurs: MaxOccurs,
539
540 pub target_type: IdentPath,
542}
543
544#[derive(Debug)]
548pub struct ComplexTypeElement<'types> {
549 pub info: &'types ElementInfo,
551
552 pub occurs: Occurs,
554
555 pub s_name: String,
557
558 pub b_name: Literal,
560
561 pub tag_name: String,
563
564 pub field_ident: Ident2,
566
567 pub variant_ident: Ident2,
569
570 pub target_type: IdentPath,
572
573 pub need_indirection: bool,
576
577 pub target_is_dynamic: bool,
580}
581
582#[derive(Debug)]
586pub struct ComplexTypeAttribute<'types> {
587 pub info: &'types AttributeInfo,
589
590 pub ident: Ident2,
592
593 pub s_name: String,
595
596 pub b_name: Literal,
598
599 pub tag_name: String,
601
602 pub is_option: bool,
604
605 pub target_type: IdentPath,
607
608 pub default_value: Option<TokenStream>,
610}
611
612#[derive(Debug, Clone)]
613enum TypeMode {
614 All,
615 Choice,
616 Sequence,
617 Simple { target_type: IdentPath },
618}
619
620impl<'types> ComplexType<'types> {
621 fn new_all(info: &'types GroupInfo, req: Request<'_, 'types>) -> Result<Self, Error> {
622 Self::new(
623 req,
624 TypeMode::All,
625 1,
626 MaxOccurs::Bounded(1),
627 &[],
628 None,
629 &info.elements,
630 info.any.as_ref(),
631 )
632 }
633
634 fn new_choice(info: &'types GroupInfo, req: Request<'_, 'types>) -> Result<Self, Error> {
635 Self::new(
636 req,
637 TypeMode::Choice,
638 1,
639 MaxOccurs::Bounded(1),
640 &[],
641 None,
642 &info.elements,
643 info.any.as_ref(),
644 )
645 }
646
647 fn new_sequence(info: &'types GroupInfo, req: Request<'_, 'types>) -> Result<Self, Error> {
648 Self::new(
649 req,
650 TypeMode::Sequence,
651 1,
652 MaxOccurs::Bounded(1),
653 &[],
654 None,
655 &info.elements,
656 info.any.as_ref(),
657 )
658 }
659
660 fn new_complex(info: &'types ComplexInfo, mut req: Request<'_, 'types>) -> Result<Self, Error> {
661 let (type_mode, elements, any_element) = match info.content.as_ref().and_then(|ident| {
662 req.types
663 .get_resolved_type(ident)
664 .map(|ty| (&ty.variant, ident))
665 }) {
666 None => (TypeMode::Sequence, &[][..], None),
667 Some((TypeVariant::All(si), _)) => (TypeMode::All, &si.elements[..], si.any.as_ref()),
668 Some((TypeVariant::Choice(si), _)) => {
669 (TypeMode::Choice, &si.elements[..], si.any.as_ref())
670 }
671 Some((TypeVariant::Sequence(si), _)) => {
672 (TypeMode::Sequence, &si.elements[..], si.any.as_ref())
673 }
674 Some((
675 TypeVariant::BuildIn(_)
676 | TypeVariant::Union(_)
677 | TypeVariant::Enumeration(_)
678 | TypeVariant::Reference(_),
679 ident,
680 )) => {
681 let content_ref = req.get_or_create_type_ref(ident.clone())?;
682 let target_type = content_ref.to_ident_path();
683
684 (TypeMode::Simple { target_type }, &[][..], None)
685 }
686 Some((x, _)) => {
687 let ident = &req.current_type_ref().type_ident;
688
689 tracing::warn!("Complex type has unexpected content: ident={ident}, info={info:#?}, content={x:#?}!");
690
691 (TypeMode::Sequence, &[][..], None)
692 }
693 };
694
695 Self::new(
696 req,
697 type_mode,
698 info.min_occurs,
699 info.max_occurs,
700 &info.attributes,
701 info.any_attribute.as_ref(),
702 elements,
703 any_element,
704 )
705 }
706
707 #[allow(clippy::too_many_arguments)]
708 fn new(
709 req: Request<'_, 'types>,
710 type_mode: TypeMode,
711 min_occurs: MinOccurs,
712 max_occurs: MaxOccurs,
713 attributes: &'types [AttributeInfo],
714 any_attribute: Option<&'types AnyAttributeInfo>,
715 elements: &'types [ElementInfo],
716 any_element: Option<&'types AnyInfo>,
717 ) -> Result<Self, Error> {
718 match type_mode {
719 TypeMode::Simple { target_type } => Self::new_simple(
720 req,
721 target_type,
722 min_occurs,
723 max_occurs,
724 attributes,
725 any_attribute,
726 ),
727 TypeMode::Choice => Self::new_enum(
728 req,
729 min_occurs,
730 max_occurs,
731 attributes,
732 any_attribute,
733 elements,
734 any_element,
735 ),
736 TypeMode::All | TypeMode::Sequence => Self::new_struct(
737 req,
738 &type_mode,
739 min_occurs,
740 max_occurs,
741 attributes,
742 any_attribute,
743 elements,
744 any_element,
745 ),
746 }
747 }
748
749 fn new_simple(
750 mut req: Request<'_, 'types>,
751 target_type: IdentPath,
752 min_occurs: MinOccurs,
753 max_occurs: MaxOccurs,
754 attributes: &'types [AttributeInfo],
755 any_attribute: Option<&'types AnyAttributeInfo>,
756 ) -> Result<Self, Error> {
757 let base = ComplexTypeBase::new(&mut req)?;
758 let occurs = Occurs::from_occurs(min_occurs, max_occurs);
759 let attributes = attributes
760 .iter()
761 .filter_map(|info| ComplexTypeAttribute::new_field(info, &mut req).transpose())
762 .collect::<Result<Vec<_>, _>>()?;
763
764 let content = ComplexTypeContent {
765 occurs,
766 is_simple: true,
767 min_occurs,
768 max_occurs,
769 target_type,
770 };
771 let type_ = ComplexTypeStruct {
772 base,
773
774 mode: StructMode::Content { content },
775
776 attributes,
777 any_attribute,
778 };
779
780 Ok(Self::Struct {
781 type_,
782 content_type: None,
783 })
784 }
785
786 fn new_enum(
787 mut req: Request<'_, 'types>,
788 min_occurs: MinOccurs,
789 max_occurs: MaxOccurs,
790 attributes: &'types [AttributeInfo],
791 any_attribute: Option<&'types AnyAttributeInfo>,
792 elements: &'types [ElementInfo],
793 any_element: Option<&'types AnyInfo>,
794 ) -> Result<Self, Error> {
795 let base = ComplexTypeBase::new(&mut req)?;
796 let occurs = Occurs::from_occurs(min_occurs, max_occurs);
797 let flatten = occurs == Occurs::Single
798 && attributes.is_empty()
799 && req.check_flags(GeneratorFlags::FLATTEN_ENUM_CONTENT);
800
801 let attributes = attributes
802 .iter()
803 .filter_map(|info| ComplexTypeAttribute::new_field(info, &mut req).transpose())
804 .collect::<Result<Vec<_>, _>>()?;
805
806 let mut any_element = any_element;
807 let mut elements = elements
808 .iter()
809 .filter_map(|info| {
810 ComplexTypeElement::new_variant(info, &mut req, occurs.is_direct()).transpose()
811 })
812 .collect::<Result<Vec<_>, _>>()?;
813
814 if flatten {
815 let type_ = ComplexTypeEnum {
816 base,
817 elements,
818 any_element,
819 any_attribute,
820 };
821
822 return Ok(ComplexType::Enum {
823 type_,
824 content_type: None,
825 });
826 }
827
828 let type_ident = &base.type_ident;
829 let content_ident = format_ident!("{type_ident}Content");
830 let has_content = occurs.is_some() && !elements.is_empty();
831
832 let content_type = has_content.then(|| {
833 let type_ = ComplexTypeEnum {
834 base: ComplexTypeBase::new_empty(content_ident.clone()),
835 elements: take(&mut elements),
836 any_element: any_element.take(),
837 any_attribute: None,
838 };
839
840 Box::new(ComplexType::Enum {
841 type_,
842 content_type: None,
843 })
844 });
845
846 let mode = if has_content {
847 let type_ref = req.current_type_ref();
848 let target_type = type_ref.to_ident_path().with_ident(content_ident.clone());
849 let content = ComplexTypeContent {
850 occurs,
851 is_simple: false,
852 min_occurs,
853 max_occurs,
854 target_type,
855 };
856
857 StructMode::Content { content }
858 } else {
859 StructMode::Empty { any_element }
860 };
861
862 let type_ = ComplexTypeStruct {
863 base,
864 mode,
865
866 attributes,
867 any_attribute,
868 };
869
870 Ok(ComplexType::Struct {
871 type_,
872 content_type,
873 })
874 }
875
876 #[allow(clippy::too_many_arguments)]
877 fn new_struct(
878 mut req: Request<'_, 'types>,
879 type_mode: &TypeMode,
880 min_occurs: MinOccurs,
881 max_occurs: MaxOccurs,
882 attributes: &'types [AttributeInfo],
883 any_attribute: Option<&'types AnyAttributeInfo>,
884 elements: &'types [ElementInfo],
885 any_element: Option<&'types AnyInfo>,
886 ) -> Result<Self, Error> {
887 let base = ComplexTypeBase::new(&mut req)?;
888 let occurs = Occurs::from_occurs(min_occurs, max_occurs);
889 let flatten =
890 occurs == Occurs::Single && req.check_flags(GeneratorFlags::FLATTEN_STRUCT_CONTENT);
891
892 let attributes = attributes
893 .iter()
894 .filter_map(|info| ComplexTypeAttribute::new_field(info, &mut req).transpose())
895 .collect::<Result<Vec<_>, _>>()?;
896
897 let elements = elements
898 .iter()
899 .filter_map(|info| {
900 ComplexTypeElement::new_field(info, &mut req, occurs.is_direct()).transpose()
901 })
902 .collect::<Result<Vec<_>, _>>()?;
903
904 if flatten {
905 let mode = match type_mode {
906 _ if elements.is_empty() => StructMode::Empty { any_element },
907 TypeMode::All => StructMode::All {
908 elements,
909 any_element,
910 },
911 TypeMode::Sequence => StructMode::Sequence {
912 elements,
913 any_element,
914 },
915 _ => crate::unreachable!(),
916 };
917
918 let type_ = ComplexTypeStruct {
919 base,
920 mode,
921
922 attributes,
923 any_attribute,
924 };
925
926 return Ok(ComplexType::Struct {
927 type_,
928 content_type: None,
929 });
930 }
931
932 let type_ident = &base.type_ident;
933 let content_ident = format_ident!("{type_ident}Content");
934 let has_content = occurs.is_some() && !elements.is_empty();
935
936 let content_type = has_content.then(|| {
937 let mode = match type_mode {
938 TypeMode::All => StructMode::All {
939 elements,
940 any_element,
941 },
942 TypeMode::Sequence => StructMode::Sequence {
943 elements,
944 any_element,
945 },
946 _ => crate::unreachable!(),
947 };
948
949 let type_ = ComplexTypeStruct {
950 base: ComplexTypeBase::new_empty(content_ident.clone()),
951 mode,
952
953 attributes: Vec::new(),
954 any_attribute: None,
955 };
956
957 Box::new(ComplexType::Struct {
958 type_,
959 content_type: None,
960 })
961 });
962
963 let mode = if has_content {
964 let type_ref = req.current_type_ref();
965 let target_type = type_ref.to_ident_path().with_ident(content_ident.clone());
966 let content = ComplexTypeContent {
967 occurs,
968 is_simple: false,
969 min_occurs,
970 max_occurs,
971 target_type,
972 };
973
974 StructMode::Content { content }
975 } else {
976 StructMode::Empty { any_element }
977 };
978
979 let type_ = ComplexTypeStruct {
980 base,
981 mode,
982
983 attributes,
984 any_attribute,
985 };
986
987 Ok(ComplexType::Struct {
988 type_,
989 content_type,
990 })
991 }
992}
993
994impl ComplexTypeBase {
995 pub(super) fn element_tag(&self) -> Option<&String> {
996 self.is_complex.then_some(self.tag_name.as_ref()).flatten()
997 }
998
999 pub(crate) fn represents_element(&self) -> bool {
1000 self.is_complex && self.tag_name.is_some() && !self.is_dynamic
1001 }
1002
1003 fn new(req: &mut Request<'_, '_>) -> Result<Self, Error> {
1004 let type_ref = req.current_type_ref();
1005 let type_ident = type_ref.type_ident.clone();
1006
1007 let mut ret = Self::new_empty(type_ident);
1008 ret.tag_name = Some(make_tag_name(req.types, req.ident));
1009 ret.trait_impls = req.make_trait_impls()?;
1010
1011 if let Some(TypeVariant::ComplexType(ci)) = req.types.get_variant(req.ident) {
1012 ret.is_complex = true;
1013 ret.is_dynamic = ci.is_dynamic;
1014 }
1015
1016 Ok(ret)
1017 }
1018
1019 fn new_empty(type_ident: Ident2) -> Self {
1020 let serializer_ident = format_ident!("{type_ident}Serializer");
1021 let serializer_state_ident = format_ident!("{type_ident}SerializerState");
1022
1023 let deserializer_ident = format_ident!("{type_ident}Deserializer");
1024 let deserializer_state_ident = format_ident!("{type_ident}DeserializerState");
1025
1026 Self {
1027 type_ident,
1028 trait_impls: Vec::new(),
1029
1030 tag_name: None,
1031 is_complex: false,
1032 is_dynamic: false,
1033
1034 serializer_ident,
1035 serializer_state_ident,
1036
1037 deserializer_ident,
1038 deserializer_state_ident,
1039 }
1040 }
1041}
1042
1043impl Deref for ComplexTypeEnum<'_> {
1044 type Target = ComplexTypeBase;
1045
1046 fn deref(&self) -> &Self::Target {
1047 &self.base
1048 }
1049}
1050
1051impl ComplexTypeStruct<'_> {
1052 pub(super) fn is_unit_struct(&self) -> bool {
1053 matches!(&self.mode, StructMode::Empty { .. }) && !self.has_attributes()
1054 }
1055
1056 pub(super) fn has_attributes(&self) -> bool {
1057 !self.attributes.is_empty()
1058 }
1059
1060 pub(super) fn has_content(&self) -> bool {
1061 match &self.mode {
1062 StructMode::All { elements, .. } | StructMode::Sequence { elements, .. } => {
1063 !elements.is_empty()
1064 }
1065 StructMode::Content { .. } => true,
1066 StructMode::Empty { .. } => false,
1067 }
1068 }
1069
1070 pub(super) fn elements(&self) -> &[ComplexTypeElement<'_>] {
1071 if let StructMode::All { elements, .. } | StructMode::Sequence { elements, .. } = &self.mode
1072 {
1073 elements
1074 } else {
1075 &[]
1076 }
1077 }
1078
1079 pub(super) fn any_element(&self) -> Option<&AnyInfo> {
1080 if let StructMode::All { any_element, .. } | StructMode::Sequence { any_element, .. } =
1081 &self.mode
1082 {
1083 *any_element
1084 } else {
1085 None
1086 }
1087 }
1088
1089 pub(super) fn content(&self) -> Option<&ComplexTypeContent> {
1090 if let StructMode::Content { content, .. } = &self.mode {
1091 Some(content)
1092 } else {
1093 None
1094 }
1095 }
1096}
1097
1098impl Deref for ComplexTypeStruct<'_> {
1099 type Target = ComplexTypeBase;
1100
1101 fn deref(&self) -> &Self::Target {
1102 &self.base
1103 }
1104}
1105
1106impl<'types> ComplexTypeElement<'types> {
1107 fn new_variant(
1108 info: &'types ElementInfo,
1109 req: &mut Request<'_, 'types>,
1110 direct_usage: bool,
1111 ) -> Result<Option<Self>, Error> {
1112 let force_box = req.box_flags.intersects(BoxFlags::ENUM_ELEMENTS);
1113
1114 Self::new(info, req, direct_usage, force_box)
1115 }
1116
1117 fn new_field(
1118 info: &'types ElementInfo,
1119 req: &mut Request<'_, 'types>,
1120 direct_usage: bool,
1121 ) -> Result<Option<Self>, Error> {
1122 let force_box = req.box_flags.intersects(BoxFlags::STRUCT_ELEMENTS);
1123
1124 Self::new(info, req, direct_usage, force_box)
1125 }
1126
1127 fn new(
1128 info: &'types ElementInfo,
1129 req: &mut Request<'_, 'types>,
1130 direct_usage: bool,
1131 force_box: bool,
1132 ) -> Result<Option<Self>, Error> {
1133 let occurs = Occurs::from_occurs(info.min_occurs, info.max_occurs);
1134 if occurs == Occurs::None {
1135 return Ok(None);
1136 }
1137
1138 let tag_name = make_tag_name(req.types, &info.ident);
1139 let s_name = info.ident.name.to_string();
1140 let b_name = Literal::byte_string(s_name.as_bytes());
1141 let field_ident = format_field_ident(&info.ident.name, info.display_name.as_deref());
1142 let variant_ident = format_variant_ident(&info.ident.name, info.display_name.as_deref());
1143
1144 let target_ref = req.get_or_create_type_ref(info.type_.clone())?;
1145 let target_type = target_ref.to_ident_path();
1146
1147 let need_box = req.current_type_ref().boxed_elements.contains(&info.ident);
1148 let need_indirection = (direct_usage && need_box) || force_box;
1149 let target_is_dynamic = is_dynamic(&info.type_, req.types);
1150
1151 Ok(Some(Self {
1152 info,
1153 occurs,
1154 s_name,
1155 b_name,
1156 tag_name,
1157 field_ident,
1158 variant_ident,
1159 target_type,
1160 need_indirection,
1161 target_is_dynamic,
1162 }))
1163 }
1164}
1165
1166impl<'types> ComplexTypeAttribute<'types> {
1167 fn new_field(
1168 info: &'types AttributeInfo,
1169 req: &mut Request<'_, 'types>,
1170 ) -> Result<Option<Self>, Error> {
1171 if info.use_ == Use::Prohibited {
1172 return Ok(None);
1173 }
1174
1175 let current_module = req.current_module();
1176 let target_ref = req.get_or_create_type_ref(info.type_.clone())?;
1177 let ident = format_field_ident(&info.ident.name, info.display_name.as_deref());
1178 let target_type = target_ref.to_ident_path();
1179 let s_name = info.ident.name.to_string();
1180 let b_name = Literal::byte_string(s_name.as_bytes());
1181 let tag_name = make_tag_name(req.types, &info.ident);
1182
1183 let default_value = info
1184 .default
1185 .as_ref()
1186 .map(|default| req.get_default(current_module, default, &info.type_))
1187 .transpose()?;
1188 let is_option = matches!((&info.use_, &default_value), (Use::Optional, None));
1189
1190 Ok(Some(Self {
1191 info,
1192 ident,
1193 s_name,
1194 b_name,
1195 tag_name,
1196 is_option,
1197 target_type,
1198 default_value,
1199 }))
1200 }
1201}
1202
1203struct Request<'a, 'types> {
1207 pub ident: &'a Ident,
1208 pub config: &'a Config<'types>,
1209
1210 state: &'a mut State<'types>,
1211}
1212
1213impl<'a, 'types> Request<'a, 'types> {
1214 fn new(ident: &'a Ident, config: &'a Config<'types>, state: &'a mut State<'types>) -> Self {
1215 Self {
1216 ident,
1217 config,
1218 state,
1219 }
1220 }
1221
1222 fn current_module(&self) -> Option<NamespaceId> {
1223 self.check_flags(GeneratorFlags::USE_MODULES)
1224 .then_some(self.ident.ns)
1225 .flatten()
1226 }
1227
1228 fn current_type_ref(&self) -> &TypeRef {
1229 self.state.cache.get(self.ident).unwrap()
1230 }
1231
1232 fn get_trait_infos(&mut self) -> &TraitInfos {
1233 self.state
1234 .trait_infos
1235 .get_or_insert_with(|| TraitInfos::new(self.config.types))
1236 }
1237
1238 fn get_or_create_type_ref(&mut self, ident: Ident) -> Result<&TypeRef, Error> {
1239 self.state.get_or_create_type_ref(self.config, ident)
1240 }
1241
1242 fn make_trait_impls(&mut self) -> Result<Vec<IdentPath>, Error> {
1243 let ident = self.ident.clone();
1244
1245 self.get_trait_infos()
1246 .get(&ident)
1247 .into_iter()
1248 .flat_map(|info| &info.traits_all)
1249 .cloned()
1250 .collect::<Vec<_>>()
1251 .into_iter()
1252 .map(|ident| {
1253 let type_ref = self.get_or_create_type_ref(ident.clone())?;
1254 let ident = format_ident!("{}Trait", type_ref.type_ident);
1255 let trait_type = type_ref.to_ident_path().with_ident(ident);
1256
1257 Ok(trait_type)
1258 })
1259 .collect::<Result<Vec<_>, _>>()
1260 }
1261
1262 fn get_default(
1263 &mut self,
1264 current_ns: Option<NamespaceId>,
1265 default: &str,
1266 ident: &Ident,
1267 ) -> Result<TokenStream, Error> {
1268 let types = self.types;
1269 let ty = types
1270 .get(ident)
1271 .ok_or_else(|| Error::UnknownType(ident.clone()))?;
1272 let type_ref = self.get_or_create_type_ref(ident.clone())?;
1273
1274 macro_rules! build_in {
1275 ($ty:ty) => {
1276 if let Ok(val) = default.parse::<$ty>() {
1277 return Ok(quote!(#val));
1278 }
1279 };
1280 }
1281
1282 match &ty.variant {
1283 TypeVariant::BuildIn(BuildInInfo::U8) => build_in!(u8),
1284 TypeVariant::BuildIn(BuildInInfo::U16) => build_in!(u16),
1285 TypeVariant::BuildIn(BuildInInfo::U32) => build_in!(u32),
1286 TypeVariant::BuildIn(BuildInInfo::U64) => build_in!(u64),
1287 TypeVariant::BuildIn(BuildInInfo::U128) => build_in!(u128),
1288 TypeVariant::BuildIn(BuildInInfo::Usize) => build_in!(usize),
1289
1290 TypeVariant::BuildIn(BuildInInfo::I8) => build_in!(i8),
1291 TypeVariant::BuildIn(BuildInInfo::I16) => build_in!(i16),
1292 TypeVariant::BuildIn(BuildInInfo::I32) => build_in!(i32),
1293 TypeVariant::BuildIn(BuildInInfo::I64) => build_in!(i64),
1294 TypeVariant::BuildIn(BuildInInfo::I128) => build_in!(i128),
1295 TypeVariant::BuildIn(BuildInInfo::Isize) => build_in!(isize),
1296
1297 TypeVariant::BuildIn(BuildInInfo::F32) => build_in!(f32),
1298 TypeVariant::BuildIn(BuildInInfo::F64) => build_in!(f64),
1299
1300 TypeVariant::BuildIn(BuildInInfo::Bool) => {
1301 match default.to_ascii_lowercase().as_str() {
1302 "true" | "yes" | "1" => return Ok(quote!(true)),
1303 "false" | "no" | "0" => return Ok(quote!(false)),
1304 _ => (),
1305 }
1306 }
1307 TypeVariant::BuildIn(BuildInInfo::String) => {
1308 return Ok(quote!(String::from(#default)));
1309 }
1310 TypeVariant::BuildIn(BuildInInfo::Custom(x)) => {
1311 if let Some(x) = x.default(default) {
1312 return Ok(x);
1313 }
1314 }
1315
1316 TypeVariant::Enumeration(ei) => {
1317 let module_path = ModulePath::from_namespace(current_ns, types);
1318 let target_type = type_ref.to_ident_path().relative_to(&module_path);
1319
1320 for var in &*ei.variants {
1321 if var.type_.is_none() && var.ident.name.as_str() == default {
1322 let variant_ident =
1323 format_variant_ident(&var.ident.name, var.display_name.as_deref());
1324
1325 return Ok(quote!(#target_type :: #variant_ident));
1326 }
1327
1328 if let Some(target_ident) = &var.type_ {
1329 if let Ok(default) = self.get_default(current_ns, default, target_ident) {
1330 let variant_ident =
1331 format_variant_ident(&var.ident.name, var.display_name.as_deref());
1332
1333 return Ok(quote!(#target_type :: #variant_ident(#default)));
1334 }
1335 }
1336 }
1337 }
1338
1339 TypeVariant::Union(ui) => {
1340 let module_path = ModulePath::from_namespace(current_ns, types);
1341 let target_type = type_ref.to_ident_path().relative_to(&module_path);
1342
1343 for ty in &*ui.types {
1344 if let Ok(code) = self.get_default(current_ns, default, &ty.type_) {
1345 let variant_ident =
1346 format_variant_ident(&ty.type_.name, ty.display_name.as_deref());
1347
1348 return Ok(quote! {
1349 #target_type :: #variant_ident ( #code )
1350 });
1351 }
1352 }
1353 }
1354
1355 TypeVariant::Reference(ti) => match Occurs::from_occurs(ti.min_occurs, ti.max_occurs) {
1356 Occurs::Single => return self.get_default(current_ns, default, &ti.type_),
1357 Occurs::DynamicList if default.is_empty() => {
1358 let module_path = ModulePath::from_namespace(current_ns, types);
1359 let target_type = type_ref.to_ident_path().relative_to(&module_path);
1360
1361 return Ok(quote! { #target_type(Vec::new()) });
1362 }
1363 _ => (),
1364 },
1365
1366 _ => (),
1367 }
1368
1369 Err(Error::InvalidDefaultValue(
1370 ident.clone(),
1371 default.to_owned(),
1372 ))
1373 }
1374}
1375
1376impl<'types> Deref for Request<'_, 'types> {
1377 type Target = Config<'types>;
1378
1379 fn deref(&self) -> &Self::Target {
1380 self.config
1381 }
1382}
1383
1384fn is_dynamic(ident: &Ident, types: &Types) -> bool {
1387 let Some(ty) = types.get(ident) else {
1388 return false;
1389 };
1390
1391 match &ty.variant {
1392 TypeVariant::Dynamic(_) => true,
1393 TypeVariant::ComplexType(ci) => ci.is_dynamic,
1394 TypeVariant::Reference(x) if x.is_single() => is_dynamic(&x.type_, types),
1395 _ => false,
1396 }
1397}
1398
1399fn make_tag_name(types: &Types, ident: &Ident) -> String {
1400 let name = ident.name.to_string();
1401
1402 if let Some(module) = ident
1403 .ns
1404 .as_ref()
1405 .and_then(|ns| types.modules.get(ns))
1406 .and_then(|module| module.name.as_ref())
1407 {
1408 format!("{module}:{name}")
1409 } else {
1410 name
1411 }
1412}
1413
1414fn make_derived_type_data<'types>(
1415 req: &mut Request<'_, 'types>,
1416 ident: &'types Ident,
1417) -> Result<DerivedType, Error> {
1418 let s_name = ident.name.to_string();
1419 let b_name = Literal::byte_string(s_name.as_bytes());
1420
1421 let ty = req
1422 .types
1423 .get(ident)
1424 .ok_or_else(|| Error::UnknownType(ident.clone()))?;
1425 let base_ident = if let TypeVariant::Dynamic(di) = &ty.variant {
1426 di.type_.clone()
1427 } else {
1428 None
1429 };
1430 let ident = base_ident.unwrap_or(ident.clone());
1431
1432 let target_ref = req.get_or_create_type_ref(ident.clone())?;
1433 let target_type = target_ref.to_ident_path();
1434 let variant_ident = format_variant_ident(&ident.name, None);
1435
1436 Ok(DerivedType {
1437 ident,
1438 b_name,
1439 target_type,
1440 variant_ident,
1441 })
1442}