{%- if enum_.is_flat -%} {{ enum_.js_docstring }} export const {{ enum_.name }} = Object.freeze({ {%- for variant in enum_.variants %} {{ variant.js_docstring|indent(4) }} {{ variant.name }}: {{ variant.discr.js_lit }}, {%- endfor %} }); // Export the FFIConverter object to make external types work. export class {{ enum_.self_type.ffi_converter }} extends FfiConverterArrayBuffer { static #validValues = Object.values({{ enum_.name }}) static read(dataStream) { // Use sequential indices (1-based) for the wire format to match the Rust scaffolding switch (dataStream.readInt32()) { {%- for variant in enum_.variants %} case {{ loop.index }}: return {{ enum_.name }}.{{ variant.name }} {%- endfor %} default: throw new UniFFITypeError("Unknown {{ enum_.name }} variant"); } } static write(dataStream, value) { // Use sequential indices (1-based) for the wire format to match the Rust scaffolding {%- for variant in enum_.variants %} if (value === {{ enum_.name }}.{{ variant.name }}) { dataStream.writeInt32({{ loop.index }}); return; } {%- endfor %} throw new UniFFITypeError("Unknown {{ enum_.name }} variant"); } static computeSize(value) { return 4; } static checkType(value) { // Check that the value is a valid enum variant if (!this.#validValues.includes(value)) { throw new UniFFITypeError(`${value} is not a valid value for {{ enum_.name }}`); } } } {%- else -%} {{ enum_.js_docstring }} export class {{ enum_.name }} {} {%- for variant in enum_.variants %} {{ variant.js_docstring }} {{enum_.name }}.{{ variant.name }} = class extends {{ enum_.name }}{ constructor( {%- if variant.fields.is_empty() -%} ) { super(); {%- else -%} { {%- for field in variant.fields -%} {{ field.name }}{% if let Some(default_val) = field.default %} = {{ default_val.js_lit }}{% else %} = undefined{% endif %}{%- if loop.last %} {% else %}, {% endif -%} {%- endfor -%} } = {}) { super(); {% for field in variant.fields -%} try { {{ field.ty.ffi_converter }}.checkType({{ field.name }}); } catch (e) { if (e instanceof UniFFITypeError) { e.addItemDescriptionPart("{{ field.name }}"); } throw e; } this.{{ field.name }} = {{ field.name }}; {%- endfor %} {%- endif %} } } {%- endfor %} // Export the FFIConverter object to make external types work. export class {{ enum_.self_type.ffi_converter }} extends FfiConverterArrayBuffer { static read(dataStream) { // Use sequential indices (1-based) for the wire format to match the Rust scaffolding switch (dataStream.readInt32()) { {%- for variant in enum_.variants %} case {{ loop.index }}: {%- if variant.fields.is_empty() %} return new {{ enum_.name }}.{{ variant.name }}(); {%- else %} return new {{ enum_.name }}.{{ variant.name }}({ {%- for field in variant.fields %} {{ field.name }}: {{ field.ty.ffi_converter }}.read(dataStream){%- if loop.last %}{% else %}, {%- endif %} {%- endfor %} }); {%- endif %} {%- endfor %} default: throw new UniFFITypeError("Unknown {{ enum_.name }} variant"); } } static write(dataStream, value) { // Use sequential indices (1-based) for the wire format to match the Rust scaffolding {%- for variant in enum_.variants %} if (value instanceof {{ enum_.name }}.{{ variant.name }}) { dataStream.writeInt32({{ loop.index }}); {%- for field in variant.fields %} {{ field.ty.ffi_converter }}.write(dataStream, value.{{ field.name }}); {%- endfor %} return; } {%- endfor %} throw new UniFFITypeError("Unknown {{ enum_.name }} variant"); } static computeSize(value) { // Size of the Int indicating the variant let totalSize = 4; {%- for variant in enum_.variants %} if (value instanceof {{ enum_.name }}.{{ variant.name }}) { {%- for field in variant.fields %} totalSize += {{ field.ty.ffi_converter }}.computeSize(value.{{ field.name }}); {%- endfor %} return totalSize; } {%- endfor %} throw new UniFFITypeError("Unknown {{ enum_.name }} variant"); } static checkType(value) { if (!(value instanceof {{ enum_.name }})) { throw new UniFFITypeError(`${value} is not a subclass instance of {{ enum_.name }}`); } } } {%- endif %}