polyxml 0.18.0__tar.gz → 0.19.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. {polyxml-0.18.0 → polyxml-0.19.1}/Cargo.lock +5 -5
  2. {polyxml-0.18.0 → polyxml-0.19.1}/Cargo.toml +1 -1
  3. {polyxml-0.18.0 → polyxml-0.19.1}/PKG-INFO +1 -1
  4. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/codegen/cpp/mod.rs +19 -2
  5. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/codegen/csharp/mod.rs +18 -3
  6. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/codegen/go/mod.rs +15 -0
  7. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/codegen/java/mod.rs +11 -1
  8. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/codegen/python/mod.rs +22 -1
  9. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/codegen/rust/mod.rs +12 -1
  10. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/codegen/typescript/mod.rs +11 -1
  11. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/tests/test_cpp_codegen.rs +1 -0
  12. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/tests/test_csharp_codegen.rs +1 -1
  13. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/tests/test_go_codegen.rs +2 -0
  14. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/tests/test_java_codegen.rs +7 -0
  15. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/tests/test_python_codegen.rs +35 -0
  16. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/tests/test_rust_codegen.rs +2 -0
  17. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/tests/test_ts_codegen.rs +6 -0
  18. {polyxml-0.18.0 → polyxml-0.19.1}/pyproject.toml +1 -1
  19. {polyxml-0.18.0 → polyxml-0.19.1}/README.md +0 -0
  20. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/Cargo.toml +0 -0
  21. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/README.md +0 -0
  22. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/benches/core_benchmarks.rs +0 -0
  23. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/codegen/mod.rs +0 -0
  24. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/converters.rs +0 -0
  25. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/error.rs +0 -0
  26. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/ir/mod.rs +0 -0
  27. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/ir/tarjan.rs +0 -0
  28. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/json.rs +0 -0
  29. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/lib.rs +0 -0
  30. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/parser.rs +0 -0
  31. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/schema.rs +0 -0
  32. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/schema_parser/mod.rs +0 -0
  33. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/serializer.rs +0 -0
  34. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/transcoder.rs +0 -0
  35. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/src/value.rs +0 -0
  36. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/tests/test_conformance.rs +0 -0
  37. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/tests/test_core.rs +0 -0
  38. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/tests/test_json.rs +0 -0
  39. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/tests/test_rust_codecs.rs +0 -0
  40. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/tests/test_schema_ir.rs +0 -0
  41. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/tests/test_security.rs +0 -0
  42. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-core/tests/test_transcoder.rs +0 -0
  43. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-python/Cargo.toml +0 -0
  44. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-python/README.md +0 -0
  45. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-python/src/lib.rs +0 -0
  46. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-python/tests/test_conformance.py +0 -0
  47. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-python/tests/test_generated_models.py +0 -0
  48. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-python/tests/test_json.py +0 -0
  49. {polyxml-0.18.0 → polyxml-0.19.1}/crates/polyxml-python/tests/test_polyxml.py +0 -0
  50. {polyxml-0.18.0 → polyxml-0.19.1}/python/polyxml/AGENT_GUIDE.md +0 -0
  51. {polyxml-0.18.0 → polyxml-0.19.1}/python/polyxml/__init__.py +0 -0
  52. {polyxml-0.18.0 → polyxml-0.19.1}/python/polyxml/compat/__init__.py +0 -0
  53. {polyxml-0.18.0 → polyxml-0.19.1}/python/polyxml/compat/xsdata.py +0 -0
  54. {polyxml-0.18.0 → polyxml-0.19.1}/python/polyxml/py.typed +0 -0
@@ -549,7 +549,7 @@ dependencies = [
549
549
 
550
550
  [[package]]
551
551
  name = "polyxml"
552
- version = "0.18.0"
552
+ version = "0.19.1"
553
553
  dependencies = [
554
554
  "criterion",
555
555
  "heck",
@@ -567,14 +567,14 @@ dependencies = [
567
567
 
568
568
  [[package]]
569
569
  name = "polyxml-c"
570
- version = "0.18.0"
570
+ version = "0.19.1"
571
571
  dependencies = [
572
572
  "polyxml",
573
573
  ]
574
574
 
575
575
  [[package]]
576
576
  name = "polyxml-cli"
577
- version = "0.18.0"
577
+ version = "0.19.1"
578
578
  dependencies = [
579
579
  "clap",
580
580
  "glob",
@@ -588,7 +588,7 @@ dependencies = [
588
588
 
589
589
  [[package]]
590
590
  name = "polyxml-js"
591
- version = "0.18.0"
591
+ version = "0.19.1"
592
592
  dependencies = [
593
593
  "napi",
594
594
  "napi-build",
@@ -598,7 +598,7 @@ dependencies = [
598
598
 
599
599
  [[package]]
600
600
  name = "polyxml-python"
601
- version = "0.18.0"
601
+ version = "0.19.1"
602
602
  dependencies = [
603
603
  "lexical-core",
604
604
  "polyxml",
@@ -3,7 +3,7 @@ resolver = "2"
3
3
  members = ["crates/polyxml-core", "crates/polyxml-python"]
4
4
 
5
5
  [workspace.package]
6
- version = "0.18.0"
6
+ version = "0.19.1"
7
7
  edition = "2021"
8
8
  rust-version = "1.80"
9
9
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: polyxml
3
- Version: 0.18.0
3
+ Version: 0.19.1
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -77,6 +77,8 @@ pub struct CppOptions {
77
77
  pub emit_cmake: bool,
78
78
  /// Emit Meson build definition (meson.build) (default: false)
79
79
  pub emit_meson: bool,
80
+ /// Custom header text to prepend to generated files (default: None)
81
+ pub custom_header: Option<String>,
80
82
  }
81
83
 
82
84
  impl Default for CppOptions {
@@ -92,6 +94,7 @@ impl Default for CppOptions {
92
94
  emit_root_aliases: true,
93
95
  emit_cmake: false,
94
96
  emit_meson: false,
97
+ custom_header: None,
95
98
  }
96
99
  }
97
100
  }
@@ -247,9 +250,16 @@ impl CppCodegen {
247
250
  /// Generate complete header-only source (`.hpp`).
248
251
  pub fn generate_header(&self, ir: &SchemaIR) -> String {
249
252
  let mut out = String::new();
253
+ if let Some(ref header) = self.options.custom_header {
254
+ let trimmed = header.trim();
255
+ if !trimmed.is_empty() {
256
+ out.push_str(trimmed);
257
+ out.push_str("\n\n");
258
+ }
259
+ }
250
260
  writeln!(
251
261
  out,
252
- "// Generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML)"
262
+ "// @generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML)"
253
263
  )
254
264
  .unwrap();
255
265
  writeln!(out, "// Target: Modern C++20/C++23 (Header-Only)").unwrap();
@@ -277,9 +287,16 @@ impl CppCodegen {
277
287
  /// Generate complete C++20 module interface unit (`.cppm`).
278
288
  pub fn generate_module_unit(&self, ir: &SchemaIR, module_name: &str) -> String {
279
289
  let mut out = String::new();
290
+ if let Some(ref header) = self.options.custom_header {
291
+ let trimmed = header.trim();
292
+ if !trimmed.is_empty() {
293
+ out.push_str(trimmed);
294
+ out.push_str("\n\n");
295
+ }
296
+ }
280
297
  writeln!(
281
298
  out,
282
- "// Generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML)"
299
+ "// @generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML)"
283
300
  )
284
301
  .unwrap();
285
302
  writeln!(out, "// Target: Modern C++20/C++23 Module Interface Unit").unwrap();
@@ -55,6 +55,8 @@ pub struct CSharpOptions {
55
55
  pub use_file_scoped_namespaces: bool,
56
56
  /// Emit root element wrapper records or aliases
57
57
  pub emit_root_records: bool,
58
+ /// Custom header text to prepend to generated files
59
+ pub custom_header: Option<String>,
58
60
  }
59
61
 
60
62
  impl Default for CSharpOptions {
@@ -69,6 +71,7 @@ impl Default for CSharpOptions {
69
71
  record_kind: CSharpRecordKind::Class,
70
72
  use_file_scoped_namespaces: true,
71
73
  emit_root_records: true,
74
+ custom_header: None,
72
75
  }
73
76
  }
74
77
  }
@@ -233,7 +236,19 @@ impl CSharpCodegen {
233
236
  pub fn generate_module(&self, ir: &SchemaIR) -> String {
234
237
  let mut out = String::new();
235
238
 
239
+ if let Some(ref header) = self.options.custom_header {
240
+ let trimmed = header.trim();
241
+ if !trimmed.is_empty() {
242
+ out.push_str(trimmed);
243
+ out.push_str("\n\n");
244
+ }
245
+ }
236
246
  writeln!(out, "// <auto-generated/>").unwrap();
247
+ writeln!(
248
+ out,
249
+ "// @generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML)"
250
+ )
251
+ .unwrap();
237
252
  writeln!(out, "#nullable enable\n").unwrap();
238
253
  writeln!(out, "using System;").unwrap();
239
254
  writeln!(out, "using System.Collections.Generic;").unwrap();
@@ -376,8 +391,8 @@ impl CSharpCodegen {
376
391
  if self.options.emit_json_attributes {
377
392
  writeln!(
378
393
  out,
379
- "{}[JsonConverter(typeof(JsonStringEnumConverter))]",
380
- indent
394
+ "{}[JsonConverter(typeof(JsonStringEnumConverter<{}>))]",
395
+ indent, enum_name
381
396
  )
382
397
  .unwrap();
383
398
  }
@@ -654,7 +669,7 @@ impl CSharpCodegen {
654
669
  || f.nillable
655
670
  || (f.cardinality.is_list() && f.cardinality.min_occurs == 0);
656
671
  let default_arg = if is_opt {
657
- "default".to_string()
672
+ format!("default({})", field_type)
658
673
  } else {
659
674
  format!("default({})!", field_type)
660
675
  };
@@ -49,6 +49,8 @@ pub struct GoOptions {
49
49
  pub validate_facets: bool,
50
50
  /// Emit top-level type aliases for root elements (default: true)
51
51
  pub emit_root_aliases: bool,
52
+ /// Custom header text to prepend to generated files (default: None)
53
+ pub custom_header: Option<String>,
52
54
  }
53
55
 
54
56
  impl Default for GoOptions {
@@ -61,6 +63,7 @@ impl Default for GoOptions {
61
63
  validate_choice_exclusivity: true,
62
64
  validate_facets: true,
63
65
  emit_root_aliases: true,
66
+ custom_header: None,
64
67
  }
65
68
  }
66
69
  }
@@ -286,11 +289,23 @@ impl GoCodegen {
286
289
 
287
290
  // Assemble final output with package and imports
288
291
  let mut out = String::new();
292
+ if let Some(ref header) = self.options.custom_header {
293
+ let trimmed = header.trim();
294
+ if !trimmed.is_empty() {
295
+ out.push_str(trimmed);
296
+ out.push_str("\n\n");
297
+ }
298
+ }
289
299
  writeln!(
290
300
  out,
291
301
  "// Code generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML). DO NOT EDIT."
292
302
  )
293
303
  .unwrap();
304
+ writeln!(
305
+ out,
306
+ "// @generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML)\n"
307
+ )
308
+ .unwrap();
294
309
 
295
310
  let pkg = to_go_package_name(&self.options.package_name);
296
311
  writeln!(out, "package {}\n", pkg).unwrap();
@@ -47,6 +47,8 @@ pub struct JavaOptions {
47
47
  pub validate_facets: bool,
48
48
  /// Emit top-level aliases for root elements (default: true)
49
49
  pub emit_root_aliases: bool,
50
+ /// Custom header text to prepend to generated files (default: None)
51
+ pub custom_header: Option<String>,
50
52
  }
51
53
 
52
54
  impl Default for JavaOptions {
@@ -57,6 +59,7 @@ impl Default for JavaOptions {
57
59
  use_records: true,
58
60
  validate_facets: true,
59
61
  emit_root_aliases: true,
62
+ custom_header: None,
60
63
  }
61
64
  }
62
65
  }
@@ -270,7 +273,14 @@ impl JavaCodegen {
270
273
  }
271
274
 
272
275
  fn emit_file_header(&self, out: &mut String) {
273
- out.push_str("// Generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML)\n");
276
+ if let Some(ref header) = self.options.custom_header {
277
+ let trimmed = header.trim();
278
+ if !trimmed.is_empty() {
279
+ out.push_str(trimmed);
280
+ out.push_str("\n\n");
281
+ }
282
+ }
283
+ out.push_str("// @generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML)\n");
274
284
  if self.options.backend.is_jackson() {
275
285
  out.push_str("// Target: Java 21+ (Records, Jackson XML/JSON Annotations)\n\n");
276
286
  } else {
@@ -39,6 +39,7 @@ pub struct PythonOptions {
39
39
  pub emit_root_aliases: bool,
40
40
  pub emit_codecs: bool,
41
41
  pub emit_json_metadata: bool,
42
+ pub custom_header: Option<String>,
42
43
  }
43
44
 
44
45
  impl Default for PythonOptions {
@@ -52,6 +53,7 @@ impl Default for PythonOptions {
52
53
  emit_root_aliases: true,
53
54
  emit_codecs: true,
54
55
  emit_json_metadata: true,
56
+ custom_header: None,
55
57
  }
56
58
  }
57
59
  }
@@ -199,7 +201,26 @@ impl PythonCodegen {
199
201
  pub fn generate_module(&self, ir: &SchemaIR) -> String {
200
202
  let mut out = String::new();
201
203
 
202
- out.push_str("# Generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML)\n");
204
+ if let Some(ref header) = self.options.custom_header {
205
+ let trimmed = header.trim();
206
+ if !trimmed.is_empty() {
207
+ for line in trimmed.lines() {
208
+ let line_trimmed = line.trim_start();
209
+ if line_trimmed.starts_with("//") {
210
+ let content = line_trimmed.strip_prefix("//").unwrap_or("");
211
+ out.push('#');
212
+ out.push_str(content);
213
+ out.push('\n');
214
+ } else {
215
+ out.push_str(line);
216
+ out.push('\n');
217
+ }
218
+ }
219
+ out.push('\n');
220
+ }
221
+ }
222
+
223
+ out.push_str("# @generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML)\n");
203
224
  out.push_str("from __future__ import annotations\n\n");
204
225
 
205
226
  self.emit_imports(&mut out, ir);
@@ -27,6 +27,8 @@ pub struct RustOptions {
27
27
  pub emit_codecs: bool,
28
28
  /// Derive rkyv::{Archive, Serialize, Deserialize} zero-copy wire format serialization (default: false).
29
29
  pub emit_rkyv: bool,
30
+ /// Custom header text to prepend to generated files (default: None).
31
+ pub custom_header: Option<String>,
30
32
  }
31
33
 
32
34
  impl Default for RustOptions {
@@ -39,6 +41,7 @@ impl Default for RustOptions {
39
41
  emit_root_aliases: true,
40
42
  emit_codecs: true,
41
43
  emit_rkyv: false,
44
+ custom_header: None,
42
45
  }
43
46
  }
44
47
  }
@@ -202,7 +205,15 @@ impl RustCodegen {
202
205
  pub fn generate_module(&self, ir: &SchemaIR) -> String {
203
206
  let mut out = String::new();
204
207
 
205
- out.push_str("// Generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML)\n");
208
+ if let Some(ref header) = self.options.custom_header {
209
+ let trimmed = header.trim();
210
+ if !trimmed.is_empty() {
211
+ out.push_str(trimmed);
212
+ out.push_str("\n\n");
213
+ }
214
+ }
215
+
216
+ out.push_str("// @generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML)\n");
206
217
  out.push_str(
207
218
  "#![allow(dead_code, unused_imports, unused_mut, unused_variables, non_camel_case_types, non_snake_case)]\n\n",
208
219
  );
@@ -49,6 +49,8 @@ pub struct TypeScriptOptions {
49
49
  pub readonly_fields: bool,
50
50
  /// Emit type aliases for top-level root XML elements (default: true)
51
51
  pub emit_root_aliases: bool,
52
+ /// Custom header text to prepend to generated files (default: None)
53
+ pub custom_header: Option<String>,
52
54
  }
53
55
 
54
56
  impl TypeScriptOptions {
@@ -71,6 +73,7 @@ impl Default for TypeScriptOptions {
71
73
  use_interface: true,
72
74
  readonly_fields: false,
73
75
  emit_root_aliases: true,
76
+ custom_header: None,
74
77
  }
75
78
  }
76
79
  }
@@ -236,8 +239,15 @@ impl TypeScriptCodegen {
236
239
  }
237
240
 
238
241
  fn emit_header(&self, out: &mut String, ir: &SchemaIR) {
242
+ if let Some(ref header) = self.options.custom_header {
243
+ let trimmed = header.trim();
244
+ if !trimmed.is_empty() {
245
+ out.push_str(trimmed);
246
+ out.push_str("\n\n");
247
+ }
248
+ }
239
249
  out.push_str("/**\n");
240
- out.push_str(" * Generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML)\n");
250
+ out.push_str(" * @generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML)\n");
241
251
  out.push_str(" * Target: TypeScript 5+\n");
242
252
  if let Some(ref ns) = ir.target_namespace {
243
253
  let _ = writeln!(out, " * Target Namespace: {}", ns);
@@ -162,6 +162,7 @@ fn test_cpp_struct_and_enum_codegen_compilation() {
162
162
  emit_root_aliases: true,
163
163
  emit_cmake: false,
164
164
  emit_meson: false,
165
+ custom_header: None,
165
166
  };
166
167
 
167
168
  let codegen = CppCodegen::new(options);
@@ -180,7 +180,7 @@ fn test_csharp_records_and_enums_generation() {
180
180
 
181
181
  assert!(cs_code.contains("using System.Text.Json.Serialization;"));
182
182
  assert!(cs_code.contains("namespace Crm.Models;"));
183
- assert!(cs_code.contains("[JsonConverter(typeof(JsonStringEnumConverter))]"));
183
+ assert!(cs_code.contains("[JsonConverter(typeof(JsonStringEnumConverter<OrderStatus>))]"));
184
184
  assert!(cs_code.contains("public enum OrderStatus"));
185
185
  assert!(cs_code.contains("[XmlEnum(\"pending\")]"));
186
186
  assert!(cs_code.contains("Pending,"));
@@ -163,6 +163,7 @@ fn test_go_struct_and_enum_generation() {
163
163
  validate_choice_exclusivity: true,
164
164
  validate_facets: true,
165
165
  emit_root_aliases: true,
166
+ custom_header: None,
166
167
  };
167
168
 
168
169
  let codegen = GoCodegen::new(options);
@@ -347,6 +348,7 @@ fn test_go_choice_mutual_exclusivity() {
347
348
  validate_choice_exclusivity: true,
348
349
  validate_facets: true,
349
350
  emit_root_aliases: true,
351
+ custom_header: None,
350
352
  };
351
353
 
352
354
  let codegen = GoCodegen::new(options);
@@ -158,6 +158,7 @@ fn test_java_records_and_enums_generation() {
158
158
  use_records: true,
159
159
  validate_facets: true,
160
160
  emit_root_aliases: true,
161
+ custom_header: None,
161
162
  };
162
163
  let codegen = JavaCodegen::new(options);
163
164
  let files = codegen.generate_files(&ir);
@@ -245,6 +246,7 @@ fn test_java_sealed_interface_choice() {
245
246
  use_records: true,
246
247
  validate_facets: true,
247
248
  emit_root_aliases: true,
249
+ custom_header: None,
248
250
  };
249
251
  let codegen = JavaCodegen::new(options);
250
252
  let files = codegen.generate_files(&ir);
@@ -298,6 +300,7 @@ fn test_java_module_container_class() {
298
300
  use_records: true,
299
301
  validate_facets: true,
300
302
  emit_root_aliases: true,
303
+ custom_header: None,
301
304
  };
302
305
  let codegen = JavaCodegen::new(options);
303
306
  let code = codegen.generate_module(&ir, "BankingModels");
@@ -407,6 +410,7 @@ fn test_java_jackson_backend_struct_annotations() {
407
410
  use_records: true,
408
411
  validate_facets: true,
409
412
  emit_root_aliases: true,
413
+ custom_header: None,
410
414
  };
411
415
  let codegen = JavaCodegen::new(options);
412
416
  let files = codegen.generate_files(&ir);
@@ -467,6 +471,7 @@ fn test_java_jackson_backend_enum_annotations() {
467
471
  use_records: true,
468
472
  validate_facets: true,
469
473
  emit_root_aliases: true,
474
+ custom_header: None,
470
475
  };
471
476
  let codegen = JavaCodegen::new(options);
472
477
  let files = codegen.generate_files(&ir);
@@ -514,6 +519,7 @@ fn test_java_jackson_backend_union_annotations() {
514
519
  use_records: true,
515
520
  validate_facets: true,
516
521
  emit_root_aliases: true,
522
+ custom_header: None,
517
523
  };
518
524
  let codegen = JavaCodegen::new(options);
519
525
  let files = codegen.generate_files(&ir);
@@ -555,6 +561,7 @@ fn test_java_jackson_backend_simple_type_annotations() {
555
561
  use_records: true,
556
562
  validate_facets: true,
557
563
  emit_root_aliases: true,
564
+ custom_header: None,
558
565
  };
559
566
  let codegen = JavaCodegen::new(options);
560
567
  let files = codegen.generate_files(&ir);
@@ -127,6 +127,7 @@ fn test_python_dataclass_codegen() {
127
127
  emit_root_aliases: true,
128
128
  emit_codecs: true,
129
129
  emit_json_metadata: true,
130
+ custom_header: None,
130
131
  });
131
132
 
132
133
  let code = codegen.generate_module(&ir);
@@ -222,6 +223,7 @@ fn test_python_pydantic_codegen_with_facets() {
222
223
  emit_root_aliases: true,
223
224
  emit_codecs: true,
224
225
  emit_json_metadata: true,
226
+ custom_header: None,
225
227
  });
226
228
 
227
229
  let code = codegen.generate_module(&ir);
@@ -399,3 +401,36 @@ fn test_python_codecs_generation() {
399
401
  assert!(!code_disabled.contains("def from_json("));
400
402
  assert!(!code_disabled.contains("def to_json("));
401
403
  }
404
+
405
+ #[test]
406
+ fn test_python_generated_tag_and_custom_header() {
407
+ let mut ir = SchemaIR::new();
408
+ ir.add_type(TypeDef::Struct(StructDef {
409
+ qname: QName::local("Item"),
410
+ base_type: None,
411
+ is_abstract: false,
412
+ fields: vec![FieldDef::new(
413
+ "name",
414
+ "name",
415
+ FieldKind::Element,
416
+ TypeRef::Primitive(PrimitiveType::String),
417
+ )],
418
+ documentation: None,
419
+ }));
420
+
421
+ // Without custom header: emits default @generated tag
422
+ let default_codegen = PythonCodegen::new(PythonOptions::default());
423
+ let default_code = default_codegen.generate_module(&ir);
424
+ assert!(default_code
425
+ .contains("# @generated by PolyXML Compiler (https://github.com/nth-bailey/PolyXML)"));
426
+ assert!(default_code.contains("from __future__ import annotations"));
427
+
428
+ // With custom header: prepends custom header
429
+ let custom_codegen = PythonCodegen::new(PythonOptions {
430
+ custom_header: Some("# ruff: noqa\n# mypy: ignore-errors".into()),
431
+ ..Default::default()
432
+ });
433
+ let custom_code = custom_codegen.generate_module(&ir);
434
+ assert!(custom_code
435
+ .starts_with("# ruff: noqa\n# mypy: ignore-errors\n\n# @generated by PolyXML Compiler"));
436
+ }
@@ -134,6 +134,7 @@ fn test_rust_zero_copy_codegen() {
134
134
  emit_root_aliases: true,
135
135
  emit_codecs: false,
136
136
  emit_rkyv: false,
137
+ custom_header: None,
137
138
  });
138
139
 
139
140
  let code = codegen.generate_module(&ir);
@@ -185,6 +186,7 @@ fn test_rust_owned_codegen() {
185
186
  emit_root_aliases: true,
186
187
  emit_codecs: false,
187
188
  emit_rkyv: false,
189
+ custom_header: None,
188
190
  });
189
191
 
190
192
  let code = codegen.generate_module(&ir);
@@ -144,6 +144,7 @@ fn test_ts_interface_and_enum_codegen() {
144
144
  use_interface: true,
145
145
  readonly_fields: false,
146
146
  emit_root_aliases: true,
147
+ custom_header: None,
147
148
  };
148
149
  let codegen = TypeScriptCodegen::new(options);
149
150
  let code = codegen.generate_module(&ir);
@@ -199,6 +200,7 @@ fn test_ts_discriminated_union_choice() {
199
200
  use_interface: true,
200
201
  readonly_fields: true,
201
202
  emit_root_aliases: true,
203
+ custom_header: None,
202
204
  };
203
205
  let codegen = TypeScriptCodegen::new(options);
204
206
  let code = codegen.generate_module(&ir);
@@ -285,6 +287,7 @@ fn test_ts_zod_schema_generation() {
285
287
  use_interface: true,
286
288
  readonly_fields: false,
287
289
  emit_root_aliases: true,
290
+ custom_header: None,
288
291
  };
289
292
  let codegen = TypeScriptCodegen::new(options);
290
293
  let code = codegen.generate_module(&ir);
@@ -352,6 +355,7 @@ fn test_ts_recursive_cycle_zod_lazy() {
352
355
  use_interface: true,
353
356
  readonly_fields: false,
354
357
  emit_root_aliases: true,
358
+ custom_header: None,
355
359
  };
356
360
  let codegen = TypeScriptCodegen::new(options);
357
361
  let code = codegen.generate_module(&ir);
@@ -488,6 +492,7 @@ fn test_ts_valibot_schema_generation() {
488
492
  use_interface: true,
489
493
  readonly_fields: false,
490
494
  emit_root_aliases: true,
495
+ custom_header: None,
491
496
  };
492
497
  let codegen = TypeScriptCodegen::new(options);
493
498
  let code = codegen.generate_module(&ir);
@@ -585,6 +590,7 @@ fn test_ts_typebox_schema_generation() {
585
590
  use_interface: true,
586
591
  readonly_fields: false,
587
592
  emit_root_aliases: true,
593
+ custom_header: None,
588
594
  };
589
595
  let codegen = TypeScriptCodegen::new(options);
590
596
  let code = codegen.generate_module(&ir);
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "polyxml"
7
- version = "0.18.0"
7
+ version = "0.19.1"
8
8
  description = "High-performance, polyglot XML data-binding engine built in Rust"
9
9
  authors = [
10
10
  { name = "Bailey Nguyen", email = "bailey.tan.nguyen@gmail.com" }
File without changes