xsd_parser/config/generator.rs
1use bitflags::bitflags;
2
3use super::IdentQuadruple;
4
5/// Configuration for the code generator.
6#[derive(Debug, Clone)]
7pub struct GeneratorConfig {
8 /// Additional flags to control the generator.
9 pub flags: GeneratorFlags,
10
11 /// Types to add to the generator before the actual data types are generated.
12 ///
13 /// See [`with_type`](crate::Generator::with_type) for more details.
14 pub types: Vec<IdentQuadruple>,
15
16 /// Specify which meta types the generator should generate data types for.
17 pub generate: Generate,
18
19 /// Postfixes that should be applied to the name of the different generated
20 /// types.
21 ///
22 /// See [`with_type_postfix`](crate::Generator::with_type_postfix) for more details.
23 pub type_postfix: TypePostfix,
24
25 /// Tell the generator how to deal with boxing.
26 pub box_flags: BoxFlags,
27
28 /// Tells the generator how to deal with type definitions.
29 pub typedef_mode: TypedefMode,
30
31 /// Type to use to store unformatted text.
32 ///
33 /// See [`Generator::text_type`](crate::Generator::text_type) for details.
34 pub text_type: String,
35
36 /// Type to use to store mixed types.
37 ///
38 /// See [`Generator::mixed_type`](crate::Generator::mixed_type) for details.
39 pub mixed_type: String,
40
41 /// Type to use to store nillable types.
42 ///
43 /// See [`Generator::nillable_type`](crate::Generator::nillable_type) for details.
44 pub nillable_type: String,
45
46 /// Type to use to store unstructured `xs:any` elements.
47 ///
48 /// See [`Generator::any_type`](crate::Generator::any_type) for details.
49 pub any_type: String,
50
51 /// Type to use to store unstructured `xs:anyAttribute` attributes.
52 ///
53 /// See [`Generator::any_attributes_type`](crate::Generator::any_attributes_type)
54 /// for details.
55 pub any_attributes_type: String,
56}
57
58impl Default for GeneratorConfig {
59 fn default() -> Self {
60 Self {
61 types: vec![],
62 type_postfix: TypePostfix::default(),
63 box_flags: BoxFlags::AUTO,
64 typedef_mode: TypedefMode::Auto,
65 generate: Generate::Named,
66 flags: GeneratorFlags::empty(),
67 text_type: "::xsd_parser_types::xml::Text".into(),
68 mixed_type: "::xsd_parser_types::xml::Mixed".into(),
69 nillable_type: "::xsd_parser_types::xml::Nillable".into(),
70 any_type: "::xsd_parser_types::xml::AnyElement".into(),
71 any_attributes_type: "::xsd_parser_types::xml::AnyAttributes".into(),
72 }
73 }
74}
75
76bitflags! {
77 /// Different flags that control what code the [`Generator`](crate::Generator)
78 /// is generating.
79 #[derive(Debug, Clone, Copy)]
80 pub struct GeneratorFlags: u32 {
81 /// None of the features are enabled.
82 ///
83 /// # Examples
84 ///
85 /// Consider the following XML schema:
86 /// ```xml
87 #[doc = include_str!("../../tests/generator/generator_flags/schema.xsd")]
88 /// ```
89 ///
90 /// Setting none of the flags will result in the following code:
91 /// ```rust
92 #[doc = include_str!("../../tests/generator/generator_flags/expected/empty.rs")]
93 /// ```
94 const NONE = 0;
95
96 /// The generated code uses modules for the different namespaces.
97 ///
98 /// # Examples
99 ///
100 /// Consider the following XML schema:
101 /// ```xml
102 #[doc = include_str!("../../tests/generator/generator_flags/schema.xsd")]
103 /// ```
104 ///
105 /// Enable the `USE_MODULES` feature only will result in the following code:
106 /// ```rust,ignore
107 #[doc = include_str!("../../tests/generator/generator_flags/expected/use_modules.rs")]
108 /// ```
109 const USE_MODULES = Self::USE_NAMESPACE_MODULES.bits();
110
111 /// The generated code uses modules for the different namespaces.
112 ///
113 /// See [`USE_MODULES`](Self::USE_MODULES) for details.
114 const USE_NAMESPACE_MODULES = 1 << 0;
115
116 /// The generated code uses modules for the different schemas.
117 ///
118 /// See [`USE_MODULES`](Self::USE_MODULES) for details.
119 const USE_SCHEMA_MODULES = 1 << 1;
120
121 /// The generator flattens the content type of choice types if it does not
122 /// define any element attributes.
123 ///
124 /// # Examples
125 ///
126 /// Consider the following XML schema:
127 /// ```xml
128 #[doc = include_str!("../../tests/generator/generator_flags/schema.xsd")]
129 /// ```
130 ///
131 /// Enable the `FLATTEN_CONTENT` feature only will result in the following code:
132 /// ```rust
133 #[doc = include_str!("../../tests/generator/generator_flags/expected/flatten_content.rs")]
134 /// ```
135 const FLATTEN_CONTENT = Self::FLATTEN_ENUM_CONTENT.bits()
136 | Self::FLATTEN_STRUCT_CONTENT.bits();
137
138 /// The generator flattens the content of enum types if possible.
139 ///
140 /// See [`FLATTEN_CONTENT`](Self::FLATTEN_CONTENT) for details.
141 const FLATTEN_ENUM_CONTENT = 1 << 2;
142
143 /// The generator flattens the content of struct types if possible.
144 ///
145 /// See [`FLATTEN_CONTENT`](Self::FLATTEN_CONTENT) for details.
146 const FLATTEN_STRUCT_CONTENT = 1 << 3;
147
148 /// Enable support for mixed types.
149 ///
150 /// This will enable code generation for mixed types. This feature needs
151 /// to be used with caution, because support for mixed types when using
152 /// `serde` is quite limited.
153 ///
154 /// # Examples
155 ///
156 /// Consider the following XML schema:
157 /// ```xml
158 #[doc = include_str!("../../tests/generator/generator_flags/schema.xsd")]
159 /// ```
160 ///
161 /// Enable the `MIXED_TYPE_SUPPORT` feature only will result in the following code:
162 /// ```rust,ignore
163 #[doc = include_str!("../../tests/generator/generator_flags/expected/mixed_type_support.rs")]
164 /// ```
165 const MIXED_TYPE_SUPPORT = 1 << 4;
166
167 /// Enable support for nillable types.
168 ///
169 /// This will enable code generation for nillable types. This feature needs
170 /// to be used with caution, because support for nillable types when using
171 /// `serde` is quite limited.
172 ///
173 /// # Examples
174 ///
175 /// Consider the following XML schema:
176 /// ```xml
177 #[doc = include_str!("../../tests/generator/generator_flags/schema.xsd")]
178 /// ```
179 ///
180 /// Enable the `NILLABLE_TYPE_SUPPORT` feature only will result in the following code:
181 /// ```rust,ignore
182 #[doc = include_str!("../../tests/generator/generator_flags/expected/nillable_type_support.rs")]
183 /// ```
184 const NILLABLE_TYPE_SUPPORT = 1 << 5;
185
186 /// Enable support for `xs:any` types.
187 ///
188 /// This will enable code generation for `xs:any` types. This feature needs
189 /// to be used with caution, because support for any types when using
190 /// `serde` is quite limited.
191 ///
192 /// # Examples
193 ///
194 /// Consider the following XML schema:
195 /// ```xml
196 #[doc = include_str!("../../tests/generator/generator_flags/schema.xsd")]
197 /// ```
198 ///
199 /// Enable the `ANY_TYPE_SUPPORT` feature only will result in the following code:
200 /// ```rust,ignore
201 #[doc = include_str!("../../tests/generator/generator_flags/expected/any_type_support.rs")]
202 /// ```
203 const ANY_TYPE_SUPPORT = 1 << 6;
204
205 /// Use absolute paths for build-in types and traits.
206 ///
207 /// Using this flag will instruct the generator to use absolute paths
208 /// for build-in types and traits (e.g. `usize`, `String` or `From`) to
209 /// avoid naming conflicts with generated types.
210 ///
211 /// # Examples
212 ///
213 /// Consider the following XML schema:
214 /// ```xml
215 #[doc = include_str!("../../tests/generator/generator_flags/schema.xsd")]
216 /// ```
217 ///
218 /// Enable the `BUILD_IN_ABSOLUTE_PATHS` feature only will result in the following code:
219 /// ```rust,ignore
220 #[doc = include_str!("../../tests/generator/generator_flags/expected/build_in_absolute_paths.rs")]
221 /// ```
222 const BUILD_IN_ABSOLUTE_PATHS = 1 << 7;
223
224 /// Use absolute paths instead of using directives for all non build-in
225 /// types and traits.
226 ///
227 /// Using this flag will instruct the generator to use absolute paths
228 /// for non build-in and generated types and traits to avoid naming
229 /// conflicts with other generated types.
230 ///
231 /// This does not include build-in types (like `usize`, `String` or `From`),
232 /// to use absolute paths for these also, you have to add the
233 /// [`BUILD_IN_ABSOLUTE_PATHS`](Self::BUILD_IN_ABSOLUTE_PATHS) as well.
234 const ABSOLUTE_PATHS_INSTEAD_USINGS = 1 << 8;
235
236 /// Enable support for advanced enums.
237 ///
238 /// This will enable support for advanced enums, which are enums that have
239 /// additional constants or associated functions for the expected values of
240 /// the enum. The values are then used to match the expected values of the
241 /// enum when deserializing instead of doing a simple match on the byte string
242 /// literal.
243 ///
244 /// Caution! If you enable this flag, you have to provide suitable constants
245 /// or associated functions for the expected values of the enum, otherwise
246 /// the generated code will not compile. You can use the
247 /// [`EnumConstantsRenderStep`](crate::pipeline::renderer::EnumConstantsRenderStep)
248 /// or the [`RenderStep::EnumConstants`](super::RenderStep::EnumConstants)
249 /// to generate suitable code for these constants and associated functions.
250 const ADVANCED_ENUMS = 1 << 9;
251 }
252}
253
254bitflags! {
255 /// Flags to tell the [`Generator`](crate::Generator) how to deal with boxed
256 /// types.
257 #[derive(Default, Debug, Clone, Copy, Eq, PartialEq)]
258 pub struct BoxFlags: u32 {
259 /// Boxed types will only be used if necessary.
260 ///
261 /// # Examples
262 ///
263 /// Consider the following XML schema:
264 /// ```xml
265 #[doc = include_str!("../../tests/generator/box_flags/schema.xsd")]
266 /// ```
267 ///
268 /// Enable the `AUTO` feature only will result in the following code:
269 /// ```rust
270 #[doc = include_str!("../../tests/generator/box_flags/expected/auto.rs")]
271 /// ```
272 const AUTO = 0;
273
274 /// Elements in a `xs:choice` type will always be boxed.
275 ///
276 /// # Examples
277 ///
278 /// Consider the following XML schema:
279 /// ```xml
280 #[doc = include_str!("../../tests/generator/box_flags/schema.xsd")]
281 /// ```
282 ///
283 /// Enable the `ENUM_ELEMENTS` feature only will result in the following code:
284 /// ```rust
285 #[doc = include_str!("../../tests/generator/box_flags/expected/enum_elements.rs")]
286 /// ```
287 const ENUM_ELEMENTS = 1 << 0;
288
289 /// Elements in a `xs:all` or `xs:sequence` type will always be boxed.
290 ///
291 /// # Examples
292 ///
293 /// Consider the following XML schema:
294 /// ```xml
295 #[doc = include_str!("../../tests/generator/box_flags/schema.xsd")]
296 /// ```
297 ///
298 /// Enable the `STRUCT_ELEMENTS` feature only will result in the following code:
299 /// ```rust
300 #[doc = include_str!("../../tests/generator/box_flags/expected/struct_elements.rs")]
301 /// ```
302 const STRUCT_ELEMENTS = 1 << 1;
303 }
304}
305
306/// Postfixed that will be added to the different types generated by the code generator.
307#[derive(Debug, Clone)]
308pub struct TypePostfix {
309 /// Postfix added to normal types (like `xs:simpleType` or `xs:complexType`).
310 pub type_: String,
311
312 /// Postfixes added to elements (like `xs:element`).
313 pub element: String,
314
315 /// Postfixes added to inline types of elements (like `xs:element`).
316 pub element_type: String,
317
318 /// Postfix for the type that is used as content for [`Nillable`](xsd_parser_types::xml::Nillable) elements.
319 pub nillable_content: String,
320
321 /// Postfix for concrete elements in a substitution group.
322 pub dynamic_element: String,
323}
324
325impl Default for TypePostfix {
326 fn default() -> Self {
327 Self {
328 type_: String::from("Type"),
329 element: String::new(),
330 element_type: String::from("ElementType"),
331 nillable_content: String::from("NotNil"),
332 dynamic_element: String::from("Dyn"),
333 }
334 }
335}
336
337/// Tells the [`Generator`](crate::Generator) how to deal with type definitions.
338#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)]
339pub enum TypedefMode {
340 /// The [`Generator`](crate::Generator) will automatically detect if a
341 /// new type struct or a simple type definition should be used
342 /// for a [`Reference`](crate::models::meta::MetaTypeVariant::Reference) type.
343 ///
344 /// Detecting the correct type automatically depends basically on the
345 /// occurrence of the references type. If the target type is only referenced
346 /// exactly once, a type definition is rendered. If a different
347 /// occurrence is used, it is wrapped in a new type struct because usually
348 /// additional code needs to be implemented for such types.
349 ///
350 /// # Examples
351 ///
352 /// Consider the following XML schema:
353 /// ```xml
354 #[doc = include_str!("../../tests/generator/typedef_mode/schema.xsd")]
355 /// ```
356 ///
357 /// If the typedef mode is set to [`TypedefMode::Auto`] the following code is rendered:
358 /// ```rust
359 #[doc = include_str!("../../tests/generator/typedef_mode/expected/auto.rs")]
360 /// ```
361 #[default]
362 Auto,
363
364 /// The [`Generator`](crate::Generator) will always use a simple type definition
365 /// for a [`Reference`](crate::models::meta::MetaTypeVariant::Reference) type.
366 ///
367 /// # Examples
368 ///
369 /// Consider the following XML schema:
370 /// ```xml
371 #[doc = include_str!("../../tests/generator/typedef_mode/schema.xsd")]
372 /// ```
373 ///
374 /// If the typedef mode is set to [`TypedefMode::Typedef`] the following code is rendered:
375 /// ```rust
376 #[doc = include_str!("../../tests/generator/typedef_mode/expected/typedef.rs")]
377 /// ```
378 Typedef,
379
380 /// The [`Generator`](crate::Generator) will always use a new type struct
381 /// for a [`Reference`](crate::models::meta::MetaTypeVariant::Reference) type.
382 ///
383 /// # Examples
384 ///
385 /// Consider the following XML schema:
386 /// ```xml
387 #[doc = include_str!("../../tests/generator/typedef_mode/schema.xsd")]
388 /// ```
389 ///
390 /// If the typedef mode is set to [`TypedefMode::NewType`] the following code is rendered:
391 /// ```rust
392 #[doc = include_str!("../../tests/generator/typedef_mode/expected/new_type.rs")]
393 /// ```
394 NewType,
395}
396
397/// Configuration which types the [`Generator`](crate::Generator) should generate
398/// code for used in [`GeneratorConfig`].
399#[derive(Debug, Clone)]
400pub enum Generate {
401 /// The generator will generate code for all types of the schemas.
402 All,
403
404 /// The generator will generate code for all types that have a name.
405 Named,
406
407 /// List of identifiers the generator will generate code for.
408 Types(Vec<IdentQuadruple>),
409}