{# Helper macros for Julia type generation #}
{#
get_type: Determines the appropriate Julia type based on attribute properties
Parameters:
- attr: Attribute object containing dtypes and other properties
- parent_name: Name of the parent struct
- object_names: List of available object type names
Returns: The appropriate Julia type as a string
#}
{% macro get_type(attr, parent_name, object_names) -%}
{%- if attr.dtypes | length > 1 -%}
{{ parent_name }}{{ attr.name | to_identifier | capitalize }}Type
{%- elif attr.dtypes[0] in object_names -%}
{{ attr.dtypes[0] }}
{%- elif attr.dtypes[0] == "string" or attr.dtypes[0] in enum_names -%}
String
{%- elif attr.dtypes[0] == "float" -%}
Float64
{%- elif attr.dtypes[0] == "integer" -%}
Int64
{%- elif attr.dtypes[0] == "boolean" -%}
Bool
{%- else -%}
{{ attr.dtypes[0] }}
{%- endif -%}
{%- endmacro %}
{#
wrap_type: Wraps types in appropriate containers based on multiplicity and optionality
Parameters:
- attr: Attribute object containing multiple and required flags
- parent_name: Name of the parent struct
- object_names: List of available object type names
Returns: The wrapped Julia type as a string
#}
{% macro wrap_type(attr, parent_name, object_names) -%}
{%- if attr.multiple -%}
Union{Vector{ {{ get_type(attr, parent_name, object_names) }} }, Nothing}
{%- else -%}
{%- if attr.required is false -%}
Union{ {{ get_type(attr, parent_name, object_names) }}, Nothing}
{%- else -%}
{{ get_type(attr, parent_name, object_names) }}
{%- endif -%}
{%- endif -%}
{%- endmacro %}
{#
generate_union_struct: Generates a union type struct for a specific dtype
Parameters:
- object_name: Name of the parent object
- attr_name: Name of the attribute
- dtype: The specific data type for this union variant
- object_names: List of available object type names
Returns: The appropriate struct definition
#}
{% macro generate_union_struct(object_name, attr_name, dtype, object_names) -%}
{%- if dtype in object_names or dtype in enum_names %}
struct {{ object_name }}{{ attr_name | to_identifier | capitalize }}{{ dtype }} <: {{ object_name }}{{ attr_name | to_identifier | capitalize }}Type
value::{{ dtype }}
end
{%- elif dtype == "string" %}
struct {{ object_name }}{{ attr_name | to_identifier | capitalize }}String <: {{ object_name }}{{ attr_name | to_identifier | capitalize }}Type
value::String
end
{%- elif dtype == "float" %}
struct {{ object_name }}{{ attr_name | to_identifier | capitalize }}Float <: {{ object_name }}{{ attr_name | to_identifier | capitalize }}Type
value::Float64
end
{%- elif dtype == "integer" %}
struct {{ object_name }}{{ attr_name | to_identifier | capitalize }}Integer <: {{ object_name }}{{ attr_name | to_identifier | capitalize }}Type
value::Int64
end
{%- elif dtype == "boolean" %}
struct {{ object_name }}{{ attr_name | to_identifier | capitalize }}Boolean <: {{ object_name }}{{ attr_name | to_identifier | capitalize }}Type
value::Bool
end
{%- else %}
struct {{ object_name }}{{ attr_name | to_identifier | capitalize }}{{ dtype | capitalize }} <: {{ object_name }}{{ attr_name | to_identifier | capitalize }}Type
value::{{ dtype }}
end
{%- endif -%}
{%- endmacro %}
# This file contains Julia type definitions with JSON serialization.
#
# WARNING: This is an auto-generated file.
# Do not edit directly - any changes will be overwritten.
module {% if title -%}{{ title | replace_lower(" ", "_") | pascal_case }}{% else %}Model{% endif %}
using JSON3
using StructTypes
#=
Type Definitions
---------------
Main struct definitions with their fields and JSON serialization support.
=#
{%- for object in objects %}
{# Generate union types for this object if any exist #}
{%- for attr in object.attributes %}
{%- if attr.dtypes | length > 1 %}
#=
Union Type Definitions for {{ object.name }}.{{ attr.name }}
---------------------
Custom union types for fields that can accept multiple types.
=#
"""
Union type for {{ object.name }}.{{ attr.name }}
"""
abstract type {{ object.name }}{{ attr.name | to_identifier | capitalize }}Type end
{%- for dtype in attr.dtypes %}
{{ generate_union_struct(object.name, attr.name, dtype, object_names) }}
{%- endfor %}
export {{ object.name }}{{ attr.name | to_identifier | capitalize }}Type
{%- for dtype in attr.dtypes %}
{%- if dtype in object_names or dtype in enum_names %}
export {{ object.name }}{{ attr.name | to_identifier | capitalize }}{{ dtype }}
{%- elif dtype == "string" %}
export {{ object.name }}{{ attr.name | to_identifier | capitalize }}String
{%- elif dtype == "float" %}
export {{ object.name }}{{ attr.name | to_identifier | capitalize }}Float
{%- elif dtype == "integer" %}
export {{ object.name }}{{ attr.name | to_identifier | capitalize }}Integer
{%- elif dtype == "boolean" %}
export {{ object.name }}{{ attr.name | to_identifier | capitalize }}Boolean
{%- else %}
export {{ object.name }}{{ attr.name | to_identifier | capitalize }}{{ dtype | capitalize }}
{%- endif %}
{%- endfor %}
{%- endif %}
{%- endfor %}
{# Generate the main struct definition #}
{%- if object.docstring %}
"""
{{ wrap(object.docstring, 70, "", "", None) }}
"""
{%- endif %}
Base.@kwdef mutable struct {{ object.name }}
{%- for attr in object.attributes %}
{%- if attr.docstring %}
"""
{{ wrap(attr.docstring, 70, "", " ", None) }}
"""
{%- endif %}
{{ attr.name | to_identifier }}::{{ wrap_type(attr, object.name, object_names) }}{% if attr.required is false %} = nothing{% endif %}
{% endfor %}
end
export {{ object.name }}
{% endfor %}
end # module {{ title | replace_lower(" ", "_") }}