xml_schema_derive/xsd/
complex_type.rs1use crate::xsd::{
2 annotation::Annotation, attribute::Attribute, complex_content::ComplexContent,
3 sequence::Sequence, simple_content::SimpleContent, Implementation, XsdContext,
4};
5use heck::ToUpperCamelCase;
6use proc_macro2::{Span, TokenStream};
7use syn::Ident;
8
9#[derive(Clone, Default, Debug, PartialEq, YaDeserialize)]
10#[yaserde(
11 rename = "complexType"
12 prefix = "xs",
13 namespace = "xs: http://www.w3.org/2001/XMLSchema"
14)]
15pub struct ComplexType {
16 #[yaserde(attribute)]
17 pub name: String,
18 #[yaserde(rename = "attribute")]
19 pub attributes: Vec<Attribute>,
20 pub sequence: Option<Sequence>,
21 #[yaserde(rename = "simpleContent")]
22 pub simple_content: Option<SimpleContent>,
23 #[yaserde(rename = "complexContent")]
24 pub complex_content: Option<ComplexContent>,
25 #[yaserde(rename = "annotation")]
26 pub annotation: Option<Annotation>,
27}
28
29impl Implementation for ComplexType {
30 fn implement(
31 &self,
32 namespace_definition: &TokenStream,
33 prefix: &Option<String>,
34 context: &XsdContext,
35 ) -> TokenStream {
36 let struct_name = Ident::new(
37 &self.name.replace('.', "_").to_upper_camel_case(),
38 Span::call_site(),
39 );
40 log::info!("Generate sequence");
41 let sequence = self
42 .sequence
43 .as_ref()
44 .map(|sequence| sequence.implement(namespace_definition, prefix, context))
45 .unwrap_or_default();
46
47 log::info!("Generate simple content");
48 let simple_content = self
49 .simple_content
50 .as_ref()
51 .map(|simple_content| simple_content.implement(namespace_definition, prefix, context))
52 .unwrap_or_default();
53
54 let complex_content = self
55 .complex_content
56 .as_ref()
57 .map(|complex_content| {
58 let complex_content_type = complex_content.get_field_implementation(context, prefix);
59 quote!(
60 #[yaserde(flatten)]
61 #complex_content_type,
62 )
63 })
64 .unwrap_or_default();
65
66 let attributes: TokenStream = self
67 .attributes
68 .iter()
69 .map(|attribute| attribute.implement(namespace_definition, prefix, context))
70 .collect();
71
72 let sub_types_implementation = self
73 .sequence
74 .as_ref()
75 .map(|sequence| sequence.get_sub_types_implementation(context, namespace_definition, prefix))
76 .unwrap_or_default();
77
78 let docs = self
79 .annotation
80 .as_ref()
81 .map(|annotation| annotation.implement(namespace_definition, prefix, context))
82 .unwrap_or_default();
83
84 quote! {
85 #docs
86
87 #[derive(Clone, Debug, Default, PartialEq, yaserde_derive::YaDeserialize, yaserde_derive::YaSerialize)]
88 #namespace_definition
89 pub struct #struct_name {
90 #sequence
91 #simple_content
92 #complex_content
93 #attributes
94 }
95
96 #sub_types_implementation
97 }
98 }
99}
100
101impl ComplexType {
102 pub fn get_field_implementation(
103 &self,
104 context: &XsdContext,
105 prefix: &Option<String>,
106 ) -> TokenStream {
107 if self.sequence.is_some() {
108 self
109 .sequence
110 .as_ref()
111 .map(|sequence| sequence.get_field_implementation(context, prefix))
112 .unwrap_or_default()
113 } else {
114 self
115 .simple_content
116 .as_ref()
117 .map(|simple_content| simple_content.get_field_implementation(context, prefix))
118 .unwrap_or_default()
119 }
120 }
121
122 pub fn get_integrated_implementation(&self, parent_name: &str) -> TokenStream {
123 if self.simple_content.is_some() {
124 return quote!(String);
125 }
126
127 if self.sequence.is_some() {
128 let list_wrapper = Ident::new(parent_name, Span::call_site());
129 return quote!(#list_wrapper);
130 }
131
132 quote!(String)
133 }
134}