Source code

Revision control

Copy as Markdown

Other Tools

{%- let type_name = e.self_type.type_name %}
# {{ type_name }}
# We want to define each variant as a nested class that's also a subclass,
# which is tricky in Python. To accomplish this we're going to create each
# class separately, then manually add the child classes to the base class's
# __dict__. All of this happens in dummy class to avoid polluting the module
# namespace.
class {{ type_name }}(Exception):
{{ e.docstring|docstring(4) -}}
pass
_UniffiTemp{{ type_name }} = {{ type_name }}
class {{ type_name }}: # type: ignore
{{ e.docstring|docstring(4) -}}
{%- for variant in e.variants -%}
{%- let variant_type_name = variant.name -%}
{%- if e.is_flat %}
class {{ variant_type_name }}(_UniffiTemp{{ type_name }}):
{{ variant.docstring|docstring(8) -}}
def __repr__(self):
return "{{ type_name }}.{{ variant_type_name }}({})".format(repr(str(self)))
{%- else %}
class {{ variant_type_name }}(_UniffiTemp{{ type_name }}):
{{ variant.docstring|docstring(8) -}}
{%- if variant.has_unnamed_fields() %}
def __init__(self, *values):
if len(values) != {{ variant.fields.len() }}:
raise TypeError(f"Expected {{ variant.fields.len() }} arguments, found {len(values)}")
{%- for field in variant.fields %}
if not isinstance(values[{{ loop.index0 }}], {{ field.ty.type_name }}):
raise TypeError(f"unexpected type for tuple element {{ loop.index0 }} - expected '{{ field.ty.type_name }}', got '{type(values[{{ loop.index0 }}])}'")
{%- endfor %}
super().__init__(", ".join(map(repr, values)))
self._values = values
def __getitem__(self, index):
return self._values[index]
{%- else %}
def __init__(self{% for field in variant.fields %}, {{ field.name }}{% endfor %}):
{%- if !variant.fields.is_empty() %}
super().__init__(", ".join([
{%- for field in variant.fields %}
"{{ field.name }}={!r}".format({{ field.name }}),
{%- endfor %}
]))
{%- for field in variant.fields %}
self.{{ field.name }} = {{ field.name }}
{%- endfor %}
{%- else %}
pass
{%- endif %}
{%- endif %}
def __repr__(self):
return "{{ type_name }}.{{ variant_type_name }}({})".format(str(self))
{%- for meth in e.methods -%}
{%- let callable = meth.callable %}
{% if callable.is_async %}async {% endif %}def {{ callable.name }}(self, {% include "CallableArgs.py" %}) -> {{ callable.return_type.type_name }}:
{{ meth.docstring|docstring(12) -}}
{%- filter indent(12) %}
{%- include "CallableBody.py" %}
{%- endfilter %}
{%- endfor %}
{%- endif %}
_UniffiTemp{{ type_name }}.{{ variant_type_name }} = {{ variant_type_name }} # type: ignore
{%- endfor %}
{{ type_name }} = _UniffiTemp{{ type_name }} # type: ignore
del _UniffiTemp{{ type_name }}
class {{ e.self_type.ffi_converter_name }}(_UniffiConverterRustBuffer):
@staticmethod
def read(buf):
variant = buf.read_i32()
{%- for variant in e.variants %}
if variant == {{ loop.index }}:
return {{ type_name }}.{{ variant.name }}(
{%- if e.is_flat %}
{{ string_type_node.ffi_converter_name }}.read(buf),
{%- else %}
{%- for field in variant.fields %}
{{ field.ty.ffi_converter_name }}.read(buf),
{%- endfor %}
{%- endif %}
)
{%- endfor %}
raise InternalError("Raw enum value doesn't match any cases")
@staticmethod
def check_lower(value):
{%- if e.variants.is_empty() %}
pass
{%- else %}
{%- for variant in e.variants %}
if isinstance(value, {{ type_name }}.{{ variant.name }}):
{%- for field in variant.fields %}
{%- if variant.has_unnamed_fields() %}
{{ field.ty.ffi_converter_name }}.check_lower(value._values[{{ loop.index0 }}])
{%- else %}
{{ field.ty.ffi_converter_name }}.check_lower(value.{{ field.name }})
{%- endif %}
{%- endfor %}
return
{%- endfor %}
{%- endif %}
@staticmethod
def write(value, buf):
{%- for variant in e.variants %}
if isinstance(value, {{ type_name }}.{{ variant.name }}):
buf.write_i32({{ loop.index }})
{%- for field in variant.fields %}
{%- if variant.has_unnamed_fields() %}
{{ field.ty.ffi_converter_name }}.write(value._values[{{ loop.index0 }}], buf)
{%- else %}
{{ field.ty.ffi_converter_name }}.write(value.{{ field.name }}, buf)
{%- endif %}
{%- endfor %}
{%- endfor %}