structurize 2.16.6__tar.gz → 2.18.0__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.
- {structurize-2.16.6/structurize.egg-info → structurize-2.18.0}/PKG-INFO +1 -1
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/__init__.py +1 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/_version.py +3 -3
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotocsharp.py +74 -10
- structurize-2.18.0/avrotize/avrotojava.py +2102 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotopython.py +4 -2
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/commands.json +671 -53
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/common.py +6 -1
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/jsonstoavro.py +518 -49
- structurize-2.18.0/avrotize/structuretocpp.py +697 -0
- structurize-2.18.0/avrotize/structuretocsv.py +365 -0
- structurize-2.18.0/avrotize/structuretodatapackage.py +659 -0
- structurize-2.18.0/avrotize/structuretodb.py +1125 -0
- structurize-2.18.0/avrotize/structuretogo.py +720 -0
- structurize-2.18.0/avrotize/structuretographql.py +502 -0
- structurize-2.18.0/avrotize/structuretoiceberg.py +355 -0
- structurize-2.18.0/avrotize/structuretokusto.py +639 -0
- structurize-2.18.0/avrotize/structuretomd.py +322 -0
- structurize-2.18.0/avrotize/structuretoproto.py +764 -0
- structurize-2.18.0/avrotize/structuretorust.py +714 -0
- structurize-2.18.0/avrotize/structuretoxsd.py +679 -0
- {structurize-2.16.6 → structurize-2.18.0/structurize.egg-info}/PKG-INFO +1 -1
- {structurize-2.16.6 → structurize-2.18.0}/structurize.egg-info/SOURCES.txt +41 -0
- structurize-2.16.6/avrotize/avrotojava.py +0 -1023
- {structurize-2.16.6 → structurize-2.18.0}/.gitignore +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/LICENSE +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/MANIFEST.in +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/README.md +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/__main__.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/asn1toavro.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotize.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotocpp.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotocsv.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotodatapackage.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotodb.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotogo.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotographql.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotoiceberg.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotojs.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotojsons.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotojstruct.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotokusto.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotomd.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotools.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotoparquet.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotoproto.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotorust.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotots.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/avrotoxsd.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/constants.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/csvtoavro.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/datapackagetoavro.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/dependency_resolver.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/jsonstostructure.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/jstructtoavro.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/kstructtoavro.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/kustotoavro.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/parquettoavro.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/proto2parser.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/proto3parser.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/prototoavro.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/structuretocsharp.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/structuretojsons.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/structuretopython.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/structuretots.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/avrotize/xsdtoavro.py +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/build.ps1 +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/build.sh +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/pyproject.toml +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/setup.cfg +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/structurize.egg-info/dependency_links.txt +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/structurize.egg-info/entry_points.txt +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/structurize.egg-info/requires.txt +0 -0
- {structurize-2.16.6 → structurize-2.18.0}/structurize.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: structurize
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.18.0
|
|
4
4
|
Summary: Tools to convert from and to JSON Structure from various other schema languages.
|
|
5
5
|
Author-email: Clemens Vasters <clemensv@microsoft.com>
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -48,6 +48,7 @@ _mappings = {
|
|
|
48
48
|
"convert_avro_to_javascript": (f"{mod}.avrotojs", "convert_avro_to_javascript"),
|
|
49
49
|
"convert_avro_schema_to_javascript": (f"{mod}.avrotojs", "convert_avro_schema_to_javascript"),
|
|
50
50
|
"convert_avro_to_markdown": (f"{mod}.avrotomd", "convert_avro_to_markdown"),
|
|
51
|
+
"convert_structure_to_markdown": (f"{mod}.structuretomd", "convert_structure_to_markdown"),
|
|
51
52
|
"convert_avro_to_cpp": (f"{mod}.avrotocpp", "convert_avro_to_cpp"),
|
|
52
53
|
"convert_avro_schema_to_cpp": (f"{mod}.avrotocpp", "convert_avro_schema_to_cpp"),
|
|
53
54
|
"convert_avro_to_go": (f"{mod}.avrotogo", "convert_avro_to_go"),
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '2.
|
|
32
|
-
__version_tuple__ = version_tuple = (2,
|
|
31
|
+
__version__ = version = '2.18.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (2, 18, 0)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'gdae473138'
|
|
@@ -567,7 +567,7 @@ class AvroToCSharp:
|
|
|
567
567
|
class_definition += \
|
|
568
568
|
f"{INDENT}public sealed class {union_class_name}"
|
|
569
569
|
if self.system_text_json_annotation:
|
|
570
|
-
class_definition += f": System.Text.Json.Serialization.JsonConverter<{union_class_name}>"
|
|
570
|
+
class_definition += f": System.Text.Json.Serialization.JsonConverter<global::{namespace}.{class_name}.{union_class_name}>"
|
|
571
571
|
class_definition += f"\n{INDENT}{{\n" + \
|
|
572
572
|
f"{INDENT*2}/// <summary>\n{INDENT*2}/// Default constructor\n{INDENT*2}/// </summary>\n" + \
|
|
573
573
|
f"{INDENT*2}public {union_class_name}() {{ }}\n"
|
|
@@ -602,7 +602,7 @@ class AvroToCSharp:
|
|
|
602
602
|
if self.system_text_json_annotation:
|
|
603
603
|
class_definition += \
|
|
604
604
|
f"\n{INDENT*2}/// <summary>\n{INDENT*2}/// Reads the JSON representation of the object.\n{INDENT*2}/// </summary>\n" + \
|
|
605
|
-
f"{INDENT*2}public override {union_class_name}? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n{INDENT*2}{{\n{INDENT*3}var element = JsonElement.ParseValue(ref reader);\n" + \
|
|
605
|
+
f"{INDENT*2}public override {union_class_name}? Read(ref Utf8JsonReader reader, System.Type typeToConvert, JsonSerializerOptions options)\n{INDENT*2}{{\n{INDENT*3}var element = JsonElement.ParseValue(ref reader);\n" + \
|
|
606
606
|
class_definition_read + \
|
|
607
607
|
f"{INDENT*3}throw new NotSupportedException(\"No record type matched the JSON data\");\n{INDENT*2}}}\n" + \
|
|
608
608
|
f"\n{INDENT*2}/// <summary>\n{INDENT*2}/// Writes the JSON representation of the object.\n{INDENT*2}/// </summary>\n" + \
|
|
@@ -612,6 +612,51 @@ class AvroToCSharp:
|
|
|
612
612
|
f"\n{INDENT*2}/// <summary>\n{INDENT*2}/// Checks if the JSON element matches the schema\n{INDENT*2}/// </summary>\n" + \
|
|
613
613
|
f"{INDENT*2}public static bool IsJsonMatch(System.Text.Json.JsonElement element)\n{INDENT*2}{{" + \
|
|
614
614
|
f"\n{INDENT*3}return "+f"\n{INDENT*3} || ".join(list_is_json_match)+f";\n{INDENT*2}}}\n"
|
|
615
|
+
|
|
616
|
+
# Generate Equals and GetHashCode for the union class
|
|
617
|
+
# Build list of property names for comparison
|
|
618
|
+
union_property_names = []
|
|
619
|
+
for union_type in union_types:
|
|
620
|
+
if union_type.startswith("Dictionary<"):
|
|
621
|
+
match = re.findall(r"Dictionary<(.+)\s*,\s*(.+)>", union_type)
|
|
622
|
+
union_property_names.append("Map" + pascal(match[0][1].rsplit('.', 1)[-1]))
|
|
623
|
+
elif union_type.startswith("List<"):
|
|
624
|
+
match = re.findall(r"List<(.+)>", union_type)
|
|
625
|
+
union_property_names.append("Array" + pascal(match[0].rsplit('.', 1)[-1]))
|
|
626
|
+
elif union_type == "byte[]":
|
|
627
|
+
union_property_names.append("bytes")
|
|
628
|
+
else:
|
|
629
|
+
prop_name = union_type.rsplit('.', 1)[-1]
|
|
630
|
+
if self.is_csharp_reserved_word(prop_name):
|
|
631
|
+
prop_name = f"@{prop_name}"
|
|
632
|
+
union_property_names.append(prop_name)
|
|
633
|
+
|
|
634
|
+
equals_conditions = " && ".join([f"Equals({name}, other.{name})" for name in union_property_names])
|
|
635
|
+
|
|
636
|
+
# HashCode.Combine only accepts up to 8 arguments, so we need to chain calls for larger unions
|
|
637
|
+
def generate_hashcode_expression(props: list) -> str:
|
|
638
|
+
if len(props) <= 8:
|
|
639
|
+
return f"HashCode.Combine({', '.join(props)})"
|
|
640
|
+
else:
|
|
641
|
+
# Chain HashCode.Combine calls: Combine(Combine(first 7...), next 7...)
|
|
642
|
+
first_batch = props[:7]
|
|
643
|
+
remaining = props[7:]
|
|
644
|
+
inner = generate_hashcode_expression(remaining)
|
|
645
|
+
return f"HashCode.Combine({', '.join(first_batch)}, {inner})"
|
|
646
|
+
|
|
647
|
+
hashcode_expression = generate_hashcode_expression(union_property_names)
|
|
648
|
+
|
|
649
|
+
class_definition += \
|
|
650
|
+
f"\n{INDENT*2}/// <summary>\n{INDENT*2}/// Determines whether the specified object is equal to the current object.\n{INDENT*2}/// </summary>\n" + \
|
|
651
|
+
f"{INDENT*2}public override bool Equals(object? obj)\n{INDENT*2}{{\n" + \
|
|
652
|
+
f"{INDENT*3}if (obj is not {union_class_name} other) return false;\n" + \
|
|
653
|
+
f"{INDENT*3}return {equals_conditions};\n" + \
|
|
654
|
+
f"{INDENT*2}}}\n" + \
|
|
655
|
+
f"\n{INDENT*2}/// <summary>\n{INDENT*2}/// Serves as the default hash function.\n{INDENT*2}/// </summary>\n" + \
|
|
656
|
+
f"{INDENT*2}public override int GetHashCode()\n{INDENT*2}{{\n" + \
|
|
657
|
+
f"{INDENT*3}return {hashcode_expression};\n" + \
|
|
658
|
+
f"{INDENT*2}}}\n"
|
|
659
|
+
|
|
615
660
|
class_definition += f"{INDENT}}}\n}}"
|
|
616
661
|
|
|
617
662
|
if write_file:
|
|
@@ -628,26 +673,34 @@ class AvroToCSharp:
|
|
|
628
673
|
if found:
|
|
629
674
|
return found
|
|
630
675
|
elif isinstance(avro_schema, dict):
|
|
631
|
-
if avro_schema
|
|
676
|
+
if avro_schema.get('type') == kind and avro_schema.get('name') == type_name and avro_schema.get('namespace', parent_namespace) == type_namespace:
|
|
632
677
|
return avro_schema
|
|
633
678
|
parent_namespace = avro_schema.get('namespace', parent_namespace)
|
|
634
679
|
if 'fields' in avro_schema and isinstance(avro_schema['fields'], list):
|
|
635
680
|
for field in avro_schema['fields']:
|
|
636
|
-
if isinstance(field,dict) and 'type' in field
|
|
637
|
-
|
|
681
|
+
if isinstance(field, dict) and 'type' in field:
|
|
682
|
+
# Recursively search within field types (including union arrays)
|
|
683
|
+
found = self.find_type(kind, field['type'], type_name, type_namespace, parent_namespace)
|
|
684
|
+
if found:
|
|
685
|
+
return found
|
|
638
686
|
return None
|
|
639
687
|
|
|
640
688
|
def is_enum_type(self, avro_type: Union[str, Dict, List]) -> bool:
|
|
641
|
-
""" Checks if a type is an enum """
|
|
689
|
+
""" Checks if a type is an enum (including nullable enums) """
|
|
642
690
|
if isinstance(avro_type, str):
|
|
643
691
|
schema = self.schema_doc
|
|
644
692
|
name = avro_type.split('.')[-1]
|
|
645
693
|
namespace = ".".join(avro_type.split('.')[:-1])
|
|
646
694
|
return self.find_type('enum', schema, name, namespace) is not None
|
|
647
695
|
elif isinstance(avro_type, list):
|
|
696
|
+
# Check for nullable enum: ["null", <enum-type>] or [<enum-type>, "null"]
|
|
697
|
+
non_null_types = [t for t in avro_type if t != 'null']
|
|
698
|
+
if len(non_null_types) == 1:
|
|
699
|
+
return self.is_enum_type(non_null_types[0])
|
|
648
700
|
return False
|
|
649
701
|
elif isinstance(avro_type, dict):
|
|
650
|
-
return avro_type
|
|
702
|
+
return avro_type.get('type') == 'enum'
|
|
703
|
+
return False
|
|
651
704
|
|
|
652
705
|
def generate_property(self, field: Dict, class_name: str, parent_namespace: str) -> str:
|
|
653
706
|
""" Generates a property """
|
|
@@ -686,7 +739,15 @@ class AvroToCSharp:
|
|
|
686
739
|
initialization = ""
|
|
687
740
|
if field_default is not None:
|
|
688
741
|
# Has explicit default value
|
|
689
|
-
|
|
742
|
+
if is_enum_type:
|
|
743
|
+
# For enum types, use qualified enum value (e.g., Type.Circle)
|
|
744
|
+
# Get the base enum type name (strip nullable ? suffix if present)
|
|
745
|
+
enum_type = field_type.rstrip('?')
|
|
746
|
+
initialization = f" = {enum_type}.{field_default};"
|
|
747
|
+
elif isinstance(field_default, str):
|
|
748
|
+
initialization = f" = \"{field_default}\";"
|
|
749
|
+
else:
|
|
750
|
+
initialization = f" = {field_default};"
|
|
690
751
|
elif field_type == "string":
|
|
691
752
|
# Non-nullable string without default should be initialized to empty string
|
|
692
753
|
initialization = " = string.Empty;"
|
|
@@ -786,12 +847,13 @@ class AvroToCSharp:
|
|
|
786
847
|
""" Retrieves fields for a given class name """
|
|
787
848
|
|
|
788
849
|
class Field:
|
|
789
|
-
def __init__(self, fn: str, ft:str, tv:Any, ct: bool, pm: bool):
|
|
850
|
+
def __init__(self, fn: str, ft:str, tv:Any, ct: bool, pm: bool, ie: bool):
|
|
790
851
|
self.field_name = fn
|
|
791
852
|
self.field_type = ft
|
|
792
853
|
self.test_value = tv
|
|
793
854
|
self.is_const = ct
|
|
794
855
|
self.is_primitive = pm
|
|
856
|
+
self.is_enum = ie
|
|
795
857
|
|
|
796
858
|
fields: List[Field] = []
|
|
797
859
|
if avro_schema and 'fields' in avro_schema:
|
|
@@ -805,11 +867,13 @@ class AvroToCSharp:
|
|
|
805
867
|
field_name = f"@{field_name}"
|
|
806
868
|
field_type = self.convert_avro_type_to_csharp(class_name, field_name, field['type'], str(avro_schema.get('namespace', '')))
|
|
807
869
|
is_class = field_type in self.generated_types and self.generated_types[field_type] == "class"
|
|
870
|
+
is_enum = self.is_enum_type(field['type'])
|
|
808
871
|
f = Field(field_name,
|
|
809
872
|
field_type,
|
|
810
873
|
(self.get_test_value(field_type) if not "const" in field else '\"'+str(field["const"])+'\"'),
|
|
811
874
|
"const" in field and field["const"] is not None,
|
|
812
|
-
not is_class
|
|
875
|
+
not is_class,
|
|
876
|
+
is_enum)
|
|
813
877
|
fields.append(f)
|
|
814
878
|
return cast(List[Any], fields)
|
|
815
879
|
|