summaryrefslogtreecommitdiffstats
path: root/toolkit/components/uniffi-bindgen-gecko-js/fixtures
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/uniffi-bindgen-gecko-js/fixtures')
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/README.md36
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/README.md1
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustArithmetic.sys.mjs492
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustCustomTypes.sys.mjs467
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustExternalTypes.sys.mjs427
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustFixtureCallbacks.sys.mjs639
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustGeometry.sys.mjs520
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustRondpoint.sys.mjs3384
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustSprites.sys.mjs687
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustTodolist.sys.mjs929
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/moz.build24
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_arithmetic.js48
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_callbacks.js47
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_custom_types.js13
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_external_types.js16
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_geometry.js29
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_rondpoint.js311
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_sprites.js28
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_todolist.js71
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_type_checking.js123
-rw-r--r--toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/xpcshell.toml19
21 files changed, 8311 insertions, 0 deletions
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/README.md b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/README.md
new file mode 100644
index 0000000000..632ba88e00
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/README.md
@@ -0,0 +1,36 @@
+This directory contains generated code for the UniFFI examples/fixtures and JS
+unit tests for it.
+
+This is only built if the `--enable-uniffi-fixtures` flag is present in
+`mozconfig`. There's no benefit to including this in a release build.
+
+To add additional examples/fixtures:
+ - For most of these steps, find the code for existing fixtures and use it as a template for the new code.
+ - Edit `toolkit/components/uniffi-bindgen-gecko-js/mach_commands.py`
+ - Add an entry to `FIXTURE_UDL_FILES`
+ - Edit `toolkit/library/rust/shared/Cargo.toml`
+ - Add an optional dependency for the fixture.
+ - Add the feature to the list of features enabled by `uniffi_fixtures`.
+ - Edit `toolkit/library/rust/shared/lib.rs`:
+ - Add an `extern crate [name]` to the `uniffi_fixtures` mod
+ - Note: [name] is the name from the `[lib]` section in the Cargo.toml
+ for the example/fixture crate. This does not always match the package
+ name for the crate.
+ - Add `[name]::reexport_uniffi_scaffolding` to the `uniffi_fixtures` mod
+ - Edit `toolkit/components/uniffi-bindgen-gecko-js/fixtures/moz.build` and add the fixture name to the `components`
+ list.
+ - Add a test module to the `toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/` directory and an entry for it
+ in `toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell.ini`
+ - Run `mach vendor rust` to vendor in the Rust code.
+ - Run `mach uniffi generate` to generate the scaffolding code.
+ - Check in any new files
+
+To run the tests:
+ - Make sure you have a `mozconfig` file containing the line `ac_add_options --enable-uniffi-fixtures`
+ - Run `mach uniffi generate` if:
+ - You've added or updated a fixture
+ - You've made changes to `uniffi-bindgen-gecko-js`
+ - Run `mach build`
+ - Run `mach xpcshell-test toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/`
+ - You can also use a path to specific test file
+ - For subsequent runs, if you only modify the test files, then you can re-run this step directly
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/README.md b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/README.md
new file mode 100644
index 0000000000..91372fd31c
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/README.md
@@ -0,0 +1 @@
+This directory is where files generated by Uniffi will be created.
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustArithmetic.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustArithmetic.sys.mjs
new file mode 100644
index 0000000000..1790f0effa
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustArithmetic.sys.mjs
@@ -0,0 +1,492 @@
+// This file was autogenerated by the `uniffi-bindgen-gecko-js` crate.
+// Trust me, you don't want to mess with it!
+
+import { UniFFITypeError } from "resource://gre/modules/UniFFI.sys.mjs";
+
+
+
+// Objects intended to be used in the unit tests
+export var UnitTestObjs = {};
+
+// Write/Read data to/from an ArrayBuffer
+class ArrayBufferDataStream {
+ constructor(arrayBuffer) {
+ this.dataView = new DataView(arrayBuffer);
+ this.pos = 0;
+ }
+
+ readUint8() {
+ let rv = this.dataView.getUint8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeUint8(value) {
+ this.dataView.setUint8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readUint16() {
+ let rv = this.dataView.getUint16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeUint16(value) {
+ this.dataView.setUint16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readUint32() {
+ let rv = this.dataView.getUint32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeUint32(value) {
+ this.dataView.setUint32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readUint64() {
+ let rv = this.dataView.getBigUint64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeUint64(value) {
+ this.dataView.setBigUint64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+
+ readInt8() {
+ let rv = this.dataView.getInt8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeInt8(value) {
+ this.dataView.setInt8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readInt16() {
+ let rv = this.dataView.getInt16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeInt16(value) {
+ this.dataView.setInt16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readInt32() {
+ let rv = this.dataView.getInt32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeInt32(value) {
+ this.dataView.setInt32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readInt64() {
+ let rv = this.dataView.getBigInt64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeInt64(value) {
+ this.dataView.setBigInt64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+ readFloat32() {
+ let rv = this.dataView.getFloat32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeFloat32(value) {
+ this.dataView.setFloat32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readFloat64() {
+ let rv = this.dataView.getFloat64(this.pos);
+ this.pos += 8;
+ return rv;
+ }
+
+ writeFloat64(value) {
+ this.dataView.setFloat64(this.pos, value);
+ this.pos += 8;
+ }
+
+
+ writeString(value) {
+ const encoder = new TextEncoder();
+ // Note: in order to efficiently write this data, we first write the
+ // string data, reserving 4 bytes for the size.
+ const dest = new Uint8Array(this.dataView.buffer, this.pos + 4);
+ const encodeResult = encoder.encodeInto(value, dest);
+ if (encodeResult.read != value.length) {
+ throw new UniFFIError(
+ "writeString: out of space when writing to ArrayBuffer. Did the computeSize() method returned the wrong result?"
+ );
+ }
+ const size = encodeResult.written;
+ // Next, go back and write the size before the string data
+ this.dataView.setUint32(this.pos, size);
+ // Finally, advance our position past both the size and string data
+ this.pos += size + 4;
+ }
+
+ readString() {
+ const decoder = new TextDecoder();
+ const size = this.readUint32();
+ const source = new Uint8Array(this.dataView.buffer, this.pos, size)
+ const value = decoder.decode(source);
+ this.pos += size;
+ return value;
+ }
+}
+
+function handleRustResult(result, liftCallback, liftErrCallback) {
+ switch (result.code) {
+ case "success":
+ return liftCallback(result.data);
+
+ case "error":
+ throw liftErrCallback(result.data);
+
+ case "internal-error":
+ let message = result.internalErrorMessage;
+ if (message) {
+ throw new UniFFIInternalError(message);
+ } else {
+ throw new UniFFIInternalError("Unknown error");
+ }
+
+ default:
+ throw new UniFFIError(`Unexpected status code: ${result.code}`);
+ }
+}
+
+class UniFFIError {
+ constructor(message) {
+ this.message = message;
+ }
+
+ toString() {
+ return `UniFFIError: ${this.message}`
+ }
+}
+
+class UniFFIInternalError extends UniFFIError {}
+
+// Base class for FFI converters
+class FfiConverter {
+ // throw `UniFFITypeError` if a value to be converted has an invalid type
+ static checkType(value) {
+ if (value === undefined ) {
+ throw new UniFFITypeError(`undefined`);
+ }
+ if (value === null ) {
+ throw new UniFFITypeError(`null`);
+ }
+ }
+}
+
+// Base class for FFI converters that lift/lower by reading/writing to an ArrayBuffer
+class FfiConverterArrayBuffer extends FfiConverter {
+ static lift(buf) {
+ return this.read(new ArrayBufferDataStream(buf));
+ }
+
+ static lower(value) {
+ const buf = new ArrayBuffer(this.computeSize(value));
+ const dataStream = new ArrayBufferDataStream(buf);
+ this.write(dataStream, value);
+ return buf;
+ }
+}
+
+// Symbols that are used to ensure that Object constructors
+// can only be used with a proper UniFFI pointer
+const uniffiObjectPtr = Symbol("uniffiObjectPtr");
+const constructUniffiObject = Symbol("constructUniffiObject");
+UnitTestObjs.uniffiObjectPtr = uniffiObjectPtr;
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterU64 extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (!Number.isSafeInteger(value)) {
+ throw new UniFFITypeError(`${value} exceeds the safe integer bounds`);
+ }
+ if (value < 0) {
+ throw new UniFFITypeError(`${value} exceeds the U64 bounds`);
+ }
+ }
+ static computeSize() {
+ return 8;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeUint64(value)
+ }
+ static read(dataStream) {
+ return dataStream.readUint64()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterBool extends FfiConverter {
+ static computeSize() {
+ return 1;
+ }
+ static lift(value) {
+ return value == 1;
+ }
+ static lower(value) {
+ if (value) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ static write(dataStream, value) {
+ dataStream.writeUint8(this.lower(value))
+ }
+ static read(dataStream) {
+ return this.lift(dataStream.readUint8())
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterString extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (typeof value !== "string") {
+ throw new UniFFITypeError(`${value} is not a string`);
+ }
+ }
+
+ static lift(buf) {
+ const decoder = new TextDecoder();
+ const utf8Arr = new Uint8Array(buf);
+ return decoder.decode(utf8Arr);
+ }
+ static lower(value) {
+ const encoder = new TextEncoder();
+ return encoder.encode(value).buffer;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeString(value);
+ }
+
+ static read(dataStream) {
+ return dataStream.readString();
+ }
+
+ static computeSize(value) {
+ const encoder = new TextEncoder();
+ return 4 + encoder.encode(value).length
+ }
+}
+
+
+
+
+export class ArithmeticError extends Error {}
+
+
+export class IntegerOverflow extends ArithmeticError {
+
+ constructor(message, ...params) {
+ super(...params);
+ this.message = message;
+ }
+ toString() {
+ return `IntegerOverflow: ${super.toString()}`
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeArithmeticError extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ switch (dataStream.readInt32()) {
+ case 1:
+ return new IntegerOverflow(FfiConverterString.read(dataStream));
+ default:
+ throw new Error("Unknown ArithmeticError variant");
+ }
+ }
+ static computeSize(value) {
+ // Size of the Int indicating the variant
+ let totalSize = 4;
+ if (value instanceof IntegerOverflow) {
+ return totalSize;
+ }
+ throw new Error("Unknown ArithmeticError variant");
+ }
+ static write(dataStream, value) {
+ if (value instanceof IntegerOverflow) {
+ dataStream.writeInt32(1);
+ return;
+ }
+ throw new Error("Unknown ArithmeticError variant");
+ }
+
+ static errorClass = ArithmeticError;
+}
+
+
+
+
+
+export function add(a,b) {
+
+ const liftResult = (result) => FfiConverterU64.lift(result);
+ const liftError = (data) => FfiConverterTypeArithmeticError.lift(data);
+ const functionCall = () => {
+ try {
+ FfiConverterU64.checkType(a)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("a");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU64.checkType(b)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("b");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 35, // arithmetic:uniffi_arithmetical_fn_func_add
+ FfiConverterU64.lower(a),
+ FfiConverterU64.lower(b),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
+
+export function div(dividend,divisor) {
+
+ const liftResult = (result) => FfiConverterU64.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU64.checkType(dividend)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("dividend");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU64.checkType(divisor)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("divisor");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 36, // arithmetic:uniffi_arithmetical_fn_func_div
+ FfiConverterU64.lower(dividend),
+ FfiConverterU64.lower(divisor),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
+
+export function equal(a,b) {
+
+ const liftResult = (result) => FfiConverterBool.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU64.checkType(a)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("a");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU64.checkType(b)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("b");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 37, // arithmetic:uniffi_arithmetical_fn_func_equal
+ FfiConverterU64.lower(a),
+ FfiConverterU64.lower(b),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
+
+export function sub(a,b) {
+
+ const liftResult = (result) => FfiConverterU64.lift(result);
+ const liftError = (data) => FfiConverterTypeArithmeticError.lift(data);
+ const functionCall = () => {
+ try {
+ FfiConverterU64.checkType(a)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("a");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU64.checkType(b)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("b");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 38, // arithmetic:uniffi_arithmetical_fn_func_sub
+ FfiConverterU64.lower(a),
+ FfiConverterU64.lower(b),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustCustomTypes.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustCustomTypes.sys.mjs
new file mode 100644
index 0000000000..286c046fa6
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustCustomTypes.sys.mjs
@@ -0,0 +1,467 @@
+// This file was autogenerated by the `uniffi-bindgen-gecko-js` crate.
+// Trust me, you don't want to mess with it!
+
+import { UniFFITypeError } from "resource://gre/modules/UniFFI.sys.mjs";
+
+
+
+// Objects intended to be used in the unit tests
+export var UnitTestObjs = {};
+
+// Write/Read data to/from an ArrayBuffer
+class ArrayBufferDataStream {
+ constructor(arrayBuffer) {
+ this.dataView = new DataView(arrayBuffer);
+ this.pos = 0;
+ }
+
+ readUint8() {
+ let rv = this.dataView.getUint8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeUint8(value) {
+ this.dataView.setUint8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readUint16() {
+ let rv = this.dataView.getUint16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeUint16(value) {
+ this.dataView.setUint16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readUint32() {
+ let rv = this.dataView.getUint32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeUint32(value) {
+ this.dataView.setUint32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readUint64() {
+ let rv = this.dataView.getBigUint64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeUint64(value) {
+ this.dataView.setBigUint64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+
+ readInt8() {
+ let rv = this.dataView.getInt8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeInt8(value) {
+ this.dataView.setInt8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readInt16() {
+ let rv = this.dataView.getInt16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeInt16(value) {
+ this.dataView.setInt16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readInt32() {
+ let rv = this.dataView.getInt32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeInt32(value) {
+ this.dataView.setInt32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readInt64() {
+ let rv = this.dataView.getBigInt64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeInt64(value) {
+ this.dataView.setBigInt64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+ readFloat32() {
+ let rv = this.dataView.getFloat32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeFloat32(value) {
+ this.dataView.setFloat32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readFloat64() {
+ let rv = this.dataView.getFloat64(this.pos);
+ this.pos += 8;
+ return rv;
+ }
+
+ writeFloat64(value) {
+ this.dataView.setFloat64(this.pos, value);
+ this.pos += 8;
+ }
+
+
+ writeString(value) {
+ const encoder = new TextEncoder();
+ // Note: in order to efficiently write this data, we first write the
+ // string data, reserving 4 bytes for the size.
+ const dest = new Uint8Array(this.dataView.buffer, this.pos + 4);
+ const encodeResult = encoder.encodeInto(value, dest);
+ if (encodeResult.read != value.length) {
+ throw new UniFFIError(
+ "writeString: out of space when writing to ArrayBuffer. Did the computeSize() method returned the wrong result?"
+ );
+ }
+ const size = encodeResult.written;
+ // Next, go back and write the size before the string data
+ this.dataView.setUint32(this.pos, size);
+ // Finally, advance our position past both the size and string data
+ this.pos += size + 4;
+ }
+
+ readString() {
+ const decoder = new TextDecoder();
+ const size = this.readUint32();
+ const source = new Uint8Array(this.dataView.buffer, this.pos, size)
+ const value = decoder.decode(source);
+ this.pos += size;
+ return value;
+ }
+}
+
+function handleRustResult(result, liftCallback, liftErrCallback) {
+ switch (result.code) {
+ case "success":
+ return liftCallback(result.data);
+
+ case "error":
+ throw liftErrCallback(result.data);
+
+ case "internal-error":
+ let message = result.internalErrorMessage;
+ if (message) {
+ throw new UniFFIInternalError(message);
+ } else {
+ throw new UniFFIInternalError("Unknown error");
+ }
+
+ default:
+ throw new UniFFIError(`Unexpected status code: ${result.code}`);
+ }
+}
+
+class UniFFIError {
+ constructor(message) {
+ this.message = message;
+ }
+
+ toString() {
+ return `UniFFIError: ${this.message}`
+ }
+}
+
+class UniFFIInternalError extends UniFFIError {}
+
+// Base class for FFI converters
+class FfiConverter {
+ // throw `UniFFITypeError` if a value to be converted has an invalid type
+ static checkType(value) {
+ if (value === undefined ) {
+ throw new UniFFITypeError(`undefined`);
+ }
+ if (value === null ) {
+ throw new UniFFITypeError(`null`);
+ }
+ }
+}
+
+// Base class for FFI converters that lift/lower by reading/writing to an ArrayBuffer
+class FfiConverterArrayBuffer extends FfiConverter {
+ static lift(buf) {
+ return this.read(new ArrayBufferDataStream(buf));
+ }
+
+ static lower(value) {
+ const buf = new ArrayBuffer(this.computeSize(value));
+ const dataStream = new ArrayBufferDataStream(buf);
+ this.write(dataStream, value);
+ return buf;
+ }
+}
+
+// Symbols that are used to ensure that Object constructors
+// can only be used with a proper UniFFI pointer
+const uniffiObjectPtr = Symbol("uniffiObjectPtr");
+const constructUniffiObject = Symbol("constructUniffiObject");
+UnitTestObjs.uniffiObjectPtr = uniffiObjectPtr;
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterI64 extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (!Number.isSafeInteger(value)) {
+ throw new UniFFITypeError(`${value} exceeds the safe integer bounds`);
+ }
+ }
+ static computeSize() {
+ return 8;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeInt64(value)
+ }
+ static read(dataStream) {
+ return dataStream.readInt64()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterString extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (typeof value !== "string") {
+ throw new UniFFITypeError(`${value} is not a string`);
+ }
+ }
+
+ static lift(buf) {
+ const decoder = new TextDecoder();
+ const utf8Arr = new Uint8Array(buf);
+ return decoder.decode(utf8Arr);
+ }
+ static lower(value) {
+ const encoder = new TextEncoder();
+ return encoder.encode(value).buffer;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeString(value);
+ }
+
+ static read(dataStream) {
+ return dataStream.readString();
+ }
+
+ static computeSize(value) {
+ const encoder = new TextEncoder();
+ return 4 + encoder.encode(value).length
+ }
+}
+
+export class CustomTypesDemo {
+ constructor({ url, handle } = {}) {
+ try {
+ FfiConverterTypeUrl.checkType(url)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("url");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterTypeHandle.checkType(handle)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("handle");
+ }
+ throw e;
+ }
+ this.url = url;
+ this.handle = handle;
+ }
+ equals(other) {
+ return (
+ this.url == other.url &&
+ this.handle == other.handle
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeCustomTypesDemo extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new CustomTypesDemo({
+ url: FfiConverterTypeUrl.read(dataStream),
+ handle: FfiConverterTypeHandle.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterTypeUrl.write(dataStream, value.url);
+ FfiConverterTypeHandle.write(dataStream, value.handle);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterTypeUrl.computeSize(value.url);
+ totalSize += FfiConverterTypeHandle.computeSize(value.handle);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof CustomTypesDemo)) {
+ throw new TypeError(`Expected 'CustomTypesDemo', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterTypeUrl.checkType(value.url);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".url");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterTypeHandle.checkType(value.handle);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".handle");
+ }
+ throw e;
+ }
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterOptionalTypeCustomTypesDemo extends FfiConverterArrayBuffer {
+ static checkType(value) {
+ if (value !== undefined && value !== null) {
+ FfiConverterTypeCustomTypesDemo.checkType(value)
+ }
+ }
+
+ static read(dataStream) {
+ const code = dataStream.readUint8(0);
+ switch (code) {
+ case 0:
+ return null
+ case 1:
+ return FfiConverterTypeCustomTypesDemo.read(dataStream)
+ default:
+ throw UniFFIError(`Unexpected code: ${code}`);
+ }
+ }
+
+ static write(dataStream, value) {
+ if (value === null || value === undefined) {
+ dataStream.writeUint8(0);
+ return;
+ }
+ dataStream.writeUint8(1);
+ FfiConverterTypeCustomTypesDemo.write(dataStream, value)
+ }
+
+ static computeSize(value) {
+ if (value === null || value === undefined) {
+ return 1;
+ }
+ return 1 + FfiConverterTypeCustomTypesDemo.computeSize(value)
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeHandle extends FfiConverter {
+ static lift(buf) {
+ return FfiConverterI64.lift(buf);
+ }
+
+ static lower(buf) {
+ return FfiConverterI64.lower(buf);
+ }
+
+ static write(dataStream, value) {
+ FfiConverterI64.write(dataStream, value);
+ }
+
+ static read(buf) {
+ return FfiConverterI64.read(buf);
+ }
+
+ static computeSize(value) {
+ return FfiConverterI64.computeSize(value);
+ }
+}
+// TODO: We should also allow JS to customize the type eventually.
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeUrl extends FfiConverter {
+ static lift(buf) {
+ return FfiConverterString.lift(buf);
+ }
+
+ static lower(buf) {
+ return FfiConverterString.lower(buf);
+ }
+
+ static write(dataStream, value) {
+ FfiConverterString.write(dataStream, value);
+ }
+
+ static read(buf) {
+ return FfiConverterString.read(buf);
+ }
+
+ static computeSize(value) {
+ return FfiConverterString.computeSize(value);
+ }
+}
+// TODO: We should also allow JS to customize the type eventually.
+
+
+
+
+
+export function getCustomTypesDemo(demo) {
+
+ const liftResult = (result) => FfiConverterTypeCustomTypesDemo.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterOptionalTypeCustomTypesDemo.checkType(demo)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("demo");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 39, // custom_types:uniffi_uniffi_custom_types_fn_func_get_custom_types_demo
+ FfiConverterOptionalTypeCustomTypesDemo.lower(demo),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustExternalTypes.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustExternalTypes.sys.mjs
new file mode 100644
index 0000000000..c01b1a58b3
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustExternalTypes.sys.mjs
@@ -0,0 +1,427 @@
+// This file was autogenerated by the `uniffi-bindgen-gecko-js` crate.
+// Trust me, you don't want to mess with it!
+
+import { UniFFITypeError } from "resource://gre/modules/UniFFI.sys.mjs";
+
+
+
+// Objects intended to be used in the unit tests
+export var UnitTestObjs = {};
+
+// Write/Read data to/from an ArrayBuffer
+class ArrayBufferDataStream {
+ constructor(arrayBuffer) {
+ this.dataView = new DataView(arrayBuffer);
+ this.pos = 0;
+ }
+
+ readUint8() {
+ let rv = this.dataView.getUint8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeUint8(value) {
+ this.dataView.setUint8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readUint16() {
+ let rv = this.dataView.getUint16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeUint16(value) {
+ this.dataView.setUint16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readUint32() {
+ let rv = this.dataView.getUint32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeUint32(value) {
+ this.dataView.setUint32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readUint64() {
+ let rv = this.dataView.getBigUint64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeUint64(value) {
+ this.dataView.setBigUint64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+
+ readInt8() {
+ let rv = this.dataView.getInt8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeInt8(value) {
+ this.dataView.setInt8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readInt16() {
+ let rv = this.dataView.getInt16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeInt16(value) {
+ this.dataView.setInt16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readInt32() {
+ let rv = this.dataView.getInt32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeInt32(value) {
+ this.dataView.setInt32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readInt64() {
+ let rv = this.dataView.getBigInt64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeInt64(value) {
+ this.dataView.setBigInt64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+ readFloat32() {
+ let rv = this.dataView.getFloat32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeFloat32(value) {
+ this.dataView.setFloat32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readFloat64() {
+ let rv = this.dataView.getFloat64(this.pos);
+ this.pos += 8;
+ return rv;
+ }
+
+ writeFloat64(value) {
+ this.dataView.setFloat64(this.pos, value);
+ this.pos += 8;
+ }
+
+
+ writeString(value) {
+ const encoder = new TextEncoder();
+ // Note: in order to efficiently write this data, we first write the
+ // string data, reserving 4 bytes for the size.
+ const dest = new Uint8Array(this.dataView.buffer, this.pos + 4);
+ const encodeResult = encoder.encodeInto(value, dest);
+ if (encodeResult.read != value.length) {
+ throw new UniFFIError(
+ "writeString: out of space when writing to ArrayBuffer. Did the computeSize() method returned the wrong result?"
+ );
+ }
+ const size = encodeResult.written;
+ // Next, go back and write the size before the string data
+ this.dataView.setUint32(this.pos, size);
+ // Finally, advance our position past both the size and string data
+ this.pos += size + 4;
+ }
+
+ readString() {
+ const decoder = new TextDecoder();
+ const size = this.readUint32();
+ const source = new Uint8Array(this.dataView.buffer, this.pos, size)
+ const value = decoder.decode(source);
+ this.pos += size;
+ return value;
+ }
+}
+
+function handleRustResult(result, liftCallback, liftErrCallback) {
+ switch (result.code) {
+ case "success":
+ return liftCallback(result.data);
+
+ case "error":
+ throw liftErrCallback(result.data);
+
+ case "internal-error":
+ let message = result.internalErrorMessage;
+ if (message) {
+ throw new UniFFIInternalError(message);
+ } else {
+ throw new UniFFIInternalError("Unknown error");
+ }
+
+ default:
+ throw new UniFFIError(`Unexpected status code: ${result.code}`);
+ }
+}
+
+class UniFFIError {
+ constructor(message) {
+ this.message = message;
+ }
+
+ toString() {
+ return `UniFFIError: ${this.message}`
+ }
+}
+
+class UniFFIInternalError extends UniFFIError {}
+
+// Base class for FFI converters
+class FfiConverter {
+ // throw `UniFFITypeError` if a value to be converted has an invalid type
+ static checkType(value) {
+ if (value === undefined ) {
+ throw new UniFFITypeError(`undefined`);
+ }
+ if (value === null ) {
+ throw new UniFFITypeError(`null`);
+ }
+ }
+}
+
+// Base class for FFI converters that lift/lower by reading/writing to an ArrayBuffer
+class FfiConverterArrayBuffer extends FfiConverter {
+ static lift(buf) {
+ return this.read(new ArrayBufferDataStream(buf));
+ }
+
+ static lower(value) {
+ const buf = new ArrayBuffer(this.computeSize(value));
+ const dataStream = new ArrayBufferDataStream(buf);
+ this.write(dataStream, value);
+ return buf;
+ }
+}
+
+// Symbols that are used to ensure that Object constructors
+// can only be used with a proper UniFFI pointer
+const uniffiObjectPtr = Symbol("uniffiObjectPtr");
+const constructUniffiObject = Symbol("constructUniffiObject");
+UnitTestObjs.uniffiObjectPtr = uniffiObjectPtr;
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterF64 extends FfiConverter {
+ static computeSize() {
+ return 8;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeFloat64(value)
+ }
+ static read(dataStream) {
+ return dataStream.readFloat64()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterString extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (typeof value !== "string") {
+ throw new UniFFITypeError(`${value} is not a string`);
+ }
+ }
+
+ static lift(buf) {
+ const decoder = new TextDecoder();
+ const utf8Arr = new Uint8Array(buf);
+ return decoder.decode(utf8Arr);
+ }
+ static lower(value) {
+ const encoder = new TextEncoder();
+ return encoder.encode(value).buffer;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeString(value);
+ }
+
+ static read(dataStream) {
+ return dataStream.readString();
+ }
+
+ static computeSize(value) {
+ const encoder = new TextEncoder();
+ return 4 + encoder.encode(value).length
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterOptionalTypeLine extends FfiConverterArrayBuffer {
+ static checkType(value) {
+ if (value !== undefined && value !== null) {
+ FfiConverterTypeLine.checkType(value)
+ }
+ }
+
+ static read(dataStream) {
+ const code = dataStream.readUint8(0);
+ switch (code) {
+ case 0:
+ return null
+ case 1:
+ return FfiConverterTypeLine.read(dataStream)
+ default:
+ throw UniFFIError(`Unexpected code: ${code}`);
+ }
+ }
+
+ static write(dataStream, value) {
+ if (value === null || value === undefined) {
+ dataStream.writeUint8(0);
+ return;
+ }
+ dataStream.writeUint8(1);
+ FfiConverterTypeLine.write(dataStream, value)
+ }
+
+ static computeSize(value) {
+ if (value === null || value === undefined) {
+ return 1;
+ }
+ return 1 + FfiConverterTypeLine.computeSize(value)
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterOptionalTypePoint extends FfiConverterArrayBuffer {
+ static checkType(value) {
+ if (value !== undefined && value !== null) {
+ FfiConverterTypePoint.checkType(value)
+ }
+ }
+
+ static read(dataStream) {
+ const code = dataStream.readUint8(0);
+ switch (code) {
+ case 0:
+ return null
+ case 1:
+ return FfiConverterTypePoint.read(dataStream)
+ default:
+ throw UniFFIError(`Unexpected code: ${code}`);
+ }
+ }
+
+ static write(dataStream, value) {
+ if (value === null || value === undefined) {
+ dataStream.writeUint8(0);
+ return;
+ }
+ dataStream.writeUint8(1);
+ FfiConverterTypePoint.write(dataStream, value)
+ }
+
+ static computeSize(value) {
+ if (value === null || value === undefined) {
+ return 1;
+ }
+ return 1 + FfiConverterTypePoint.computeSize(value)
+ }
+}
+
+import {
+ FfiConverterTypeLine,
+ Line,
+} from "resource://gre/modules/RustGeometry.sys.mjs";
+
+// Export the FFIConverter object to make external types work.
+export { FfiConverterTypeLine, Line };
+
+import {
+ FfiConverterTypePoint,
+ Point,
+} from "resource://gre/modules/RustGeometry.sys.mjs";
+
+// Export the FFIConverter object to make external types work.
+export { FfiConverterTypePoint, Point };
+
+
+
+
+
+export function gradient(value) {
+
+ const liftResult = (result) => FfiConverterF64.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterOptionalTypeLine.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 40, // external_types:uniffi_uniffi_fixture_external_types_fn_func_gradient
+ FfiConverterOptionalTypeLine.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
+
+export function intersection(ln1,ln2) {
+
+ const liftResult = (result) => FfiConverterOptionalTypePoint.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypeLine.checkType(ln1)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("ln1");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterTypeLine.checkType(ln2)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("ln2");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 41, // external_types:uniffi_uniffi_fixture_external_types_fn_func_intersection
+ FfiConverterTypeLine.lower(ln1),
+ FfiConverterTypeLine.lower(ln2),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustFixtureCallbacks.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustFixtureCallbacks.sys.mjs
new file mode 100644
index 0000000000..75fe81a458
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustFixtureCallbacks.sys.mjs
@@ -0,0 +1,639 @@
+// This file was autogenerated by the `uniffi-bindgen-gecko-js` crate.
+// Trust me, you don't want to mess with it!
+
+import { UniFFITypeError } from "resource://gre/modules/UniFFI.sys.mjs";
+
+
+
+// Objects intended to be used in the unit tests
+export var UnitTestObjs = {};
+
+// Write/Read data to/from an ArrayBuffer
+class ArrayBufferDataStream {
+ constructor(arrayBuffer) {
+ this.dataView = new DataView(arrayBuffer);
+ this.pos = 0;
+ }
+
+ readUint8() {
+ let rv = this.dataView.getUint8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeUint8(value) {
+ this.dataView.setUint8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readUint16() {
+ let rv = this.dataView.getUint16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeUint16(value) {
+ this.dataView.setUint16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readUint32() {
+ let rv = this.dataView.getUint32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeUint32(value) {
+ this.dataView.setUint32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readUint64() {
+ let rv = this.dataView.getBigUint64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeUint64(value) {
+ this.dataView.setBigUint64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+
+ readInt8() {
+ let rv = this.dataView.getInt8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeInt8(value) {
+ this.dataView.setInt8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readInt16() {
+ let rv = this.dataView.getInt16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeInt16(value) {
+ this.dataView.setInt16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readInt32() {
+ let rv = this.dataView.getInt32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeInt32(value) {
+ this.dataView.setInt32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readInt64() {
+ let rv = this.dataView.getBigInt64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeInt64(value) {
+ this.dataView.setBigInt64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+ readFloat32() {
+ let rv = this.dataView.getFloat32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeFloat32(value) {
+ this.dataView.setFloat32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readFloat64() {
+ let rv = this.dataView.getFloat64(this.pos);
+ this.pos += 8;
+ return rv;
+ }
+
+ writeFloat64(value) {
+ this.dataView.setFloat64(this.pos, value);
+ this.pos += 8;
+ }
+
+
+ writeString(value) {
+ const encoder = new TextEncoder();
+ // Note: in order to efficiently write this data, we first write the
+ // string data, reserving 4 bytes for the size.
+ const dest = new Uint8Array(this.dataView.buffer, this.pos + 4);
+ const encodeResult = encoder.encodeInto(value, dest);
+ if (encodeResult.read != value.length) {
+ throw new UniFFIError(
+ "writeString: out of space when writing to ArrayBuffer. Did the computeSize() method returned the wrong result?"
+ );
+ }
+ const size = encodeResult.written;
+ // Next, go back and write the size before the string data
+ this.dataView.setUint32(this.pos, size);
+ // Finally, advance our position past both the size and string data
+ this.pos += size + 4;
+ }
+
+ readString() {
+ const decoder = new TextDecoder();
+ const size = this.readUint32();
+ const source = new Uint8Array(this.dataView.buffer, this.pos, size)
+ const value = decoder.decode(source);
+ this.pos += size;
+ return value;
+ }
+}
+
+function handleRustResult(result, liftCallback, liftErrCallback) {
+ switch (result.code) {
+ case "success":
+ return liftCallback(result.data);
+
+ case "error":
+ throw liftErrCallback(result.data);
+
+ case "internal-error":
+ let message = result.internalErrorMessage;
+ if (message) {
+ throw new UniFFIInternalError(message);
+ } else {
+ throw new UniFFIInternalError("Unknown error");
+ }
+
+ default:
+ throw new UniFFIError(`Unexpected status code: ${result.code}`);
+ }
+}
+
+class UniFFIError {
+ constructor(message) {
+ this.message = message;
+ }
+
+ toString() {
+ return `UniFFIError: ${this.message}`
+ }
+}
+
+class UniFFIInternalError extends UniFFIError {}
+
+// Base class for FFI converters
+class FfiConverter {
+ // throw `UniFFITypeError` if a value to be converted has an invalid type
+ static checkType(value) {
+ if (value === undefined ) {
+ throw new UniFFITypeError(`undefined`);
+ }
+ if (value === null ) {
+ throw new UniFFITypeError(`null`);
+ }
+ }
+}
+
+// Base class for FFI converters that lift/lower by reading/writing to an ArrayBuffer
+class FfiConverterArrayBuffer extends FfiConverter {
+ static lift(buf) {
+ return this.read(new ArrayBufferDataStream(buf));
+ }
+
+ static lower(value) {
+ const buf = new ArrayBuffer(this.computeSize(value));
+ const dataStream = new ArrayBufferDataStream(buf);
+ this.write(dataStream, value);
+ return buf;
+ }
+}
+
+// Symbols that are used to ensure that Object constructors
+// can only be used with a proper UniFFI pointer
+const uniffiObjectPtr = Symbol("uniffiObjectPtr");
+const constructUniffiObject = Symbol("constructUniffiObject");
+UnitTestObjs.uniffiObjectPtr = uniffiObjectPtr;
+
+
+/**
+ * Handler for a single UniFFI CallbackInterface
+ *
+ * This class stores objects that implement a callback interface in a handle
+ * map, allowing them to be referenced by the Rust code using an integer
+ * handle.
+ *
+ * While the callback object is stored in the map, it allows the Rust code to
+ * call methods on the object using the callback object handle, a method id,
+ * and an ArrayBuffer packed with the method arguments.
+ *
+ * When the Rust code drops its reference, it sends a call with the methodId=0,
+ * which causes callback object to be removed from the map.
+ */
+class UniFFICallbackHandler {
+ #name;
+ #interfaceId;
+ #handleCounter;
+ #handleMap;
+ #methodHandlers;
+ #allowNewCallbacks
+
+ /**
+ * Create a UniFFICallbackHandler
+ * @param {string} name - Human-friendly name for this callback interface
+ * @param {int} interfaceId - Interface ID for this CallbackInterface.
+ * @param {UniFFICallbackMethodHandler[]} methodHandlers -- UniFFICallbackHandler for each method, in the same order as the UDL file
+ */
+ constructor(name, interfaceId, methodHandlers) {
+ this.#name = name;
+ this.#interfaceId = interfaceId;
+ this.#handleCounter = 0;
+ this.#handleMap = new Map();
+ this.#methodHandlers = methodHandlers;
+ this.#allowNewCallbacks = true;
+
+ UniFFIScaffolding.registerCallbackHandler(this.#interfaceId, this.invokeCallback.bind(this));
+ Services.obs.addObserver(this, "xpcom-shutdown");
+ }
+
+ /**
+ * Store a callback object in the handle map and return the handle
+ *
+ * @param {obj} callbackObj - Object that implements the callback interface
+ * @returns {int} - Handle for this callback object, this is what gets passed back to Rust.
+ */
+ storeCallbackObj(callbackObj) {
+ if (!this.#allowNewCallbacks) {
+ throw new UniFFIError(`No new callbacks allowed for ${this.#name}`);
+ }
+ const handle = this.#handleCounter;
+ this.#handleCounter += 1;
+ this.#handleMap.set(handle, new UniFFICallbackHandleMapEntry(callbackObj, Components.stack.caller.formattedStack.trim()));
+ return handle;
+ }
+
+ /**
+ * Get a previously stored callback object
+ *
+ * @param {int} handle - Callback object handle, returned from `storeCallbackObj()`
+ * @returns {obj} - Callback object
+ */
+ getCallbackObj(handle) {
+ return this.#handleMap.get(handle).callbackObj;
+ }
+
+ /**
+ * Set if new callbacks are allowed for this handler
+ *
+ * This is called with false during shutdown to ensure the callback maps don't
+ * prevent JS objects from being GCed.
+ */
+ setAllowNewCallbacks(allow) {
+ this.#allowNewCallbacks = allow
+ }
+
+ /**
+ * Check that no callbacks are currently registered
+ *
+ * If there are callbacks registered a UniFFIError will be thrown. This is
+ * called during shutdown to generate an alert if there are leaked callback
+ * interfaces.
+ */
+ assertNoRegisteredCallbacks() {
+ if (this.#handleMap.size > 0) {
+ const entry = this.#handleMap.values().next().value;
+ throw new UniFFIError(`UniFFI interface ${this.#name} has ${this.#handleMap.size} registered callbacks at xpcom-shutdown. This likely indicates a UniFFI callback leak.\nStack trace for the first leaked callback:\n${entry.stackTrace}.`);
+ }
+ }
+
+ /**
+ * Invoke a method on a stored callback object
+ * @param {int} handle - Object handle
+ * @param {int} methodId - Method identifier. This the 1-based index of
+ * the method from the UDL file. 0 is the special drop method, which
+ * removes the callback object from the handle map.
+ * @param {ArrayBuffer} argsArrayBuffer - Arguments to pass to the method, packed in an ArrayBuffer
+ */
+ invokeCallback(handle, methodId, argsArrayBuffer) {
+ try {
+ this.#invokeCallbackInner(handle, methodId, argsArrayBuffer);
+ } catch (e) {
+ console.error(`internal error invoking callback: ${e}`)
+ }
+ }
+
+ #invokeCallbackInner(handle, methodId, argsArrayBuffer) {
+ const callbackObj = this.getCallbackObj(handle);
+ if (callbackObj === undefined) {
+ throw new UniFFIError(`${this.#name}: invalid callback handle id: ${handle}`);
+ }
+
+ // Special-cased drop method, remove the object from the handle map and
+ // return an empty array buffer
+ if (methodId == 0) {
+ this.#handleMap.delete(handle);
+ return;
+ }
+
+ // Get the method data, converting from 1-based indexing
+ const methodHandler = this.#methodHandlers[methodId - 1];
+ if (methodHandler === undefined) {
+ throw new UniFFIError(`${this.#name}: invalid method id: ${methodId}`)
+ }
+
+ methodHandler.call(callbackObj, argsArrayBuffer);
+ }
+
+ /**
+ * xpcom-shutdown observer method
+ *
+ * This handles:
+ * - Deregistering ourselves as the UniFFI callback handler
+ * - Checks for any leftover stored callbacks which indicate memory leaks
+ */
+ observe(aSubject, aTopic, aData) {
+ if (aTopic == "xpcom-shutdown") {
+ try {
+ this.setAllowNewCallbacks(false);
+ this.assertNoRegisteredCallbacks();
+ UniFFIScaffolding.deregisterCallbackHandler(this.#interfaceId);
+ } catch (ex) {
+ console.error(`UniFFI Callback interface error during xpcom-shutdown: ${ex}`);
+ Cc["@mozilla.org/xpcom/debug;1"]
+ .getService(Ci.nsIDebug2)
+ .abort(ex.filename, ex.lineNumber);
+ }
+ }
+ }
+}
+
+/**
+ * Handles calling a single method for a callback interface
+ */
+class UniFFICallbackMethodHandler {
+ #name;
+ #argsConverters;
+
+ /**
+ * Create a UniFFICallbackMethodHandler
+
+ * @param {string} name -- Name of the method to call on the callback object
+ * @param {FfiConverter[]} argsConverters - FfiConverter for each argument type
+ */
+ constructor(name, argsConverters) {
+ this.#name = name;
+ this.#argsConverters = argsConverters;
+ }
+
+ /**
+ * Invoke the method
+ *
+ * @param {obj} callbackObj -- Object implementing the callback interface for this method
+ * @param {ArrayBuffer} argsArrayBuffer -- Arguments for the method, packed in an ArrayBuffer
+ */
+ call(callbackObj, argsArrayBuffer) {
+ const argsStream = new ArrayBufferDataStream(argsArrayBuffer);
+ const args = this.#argsConverters.map(converter => converter.read(argsStream));
+ callbackObj[this.#name](...args);
+ }
+}
+
+/**
+ * UniFFICallbackHandler.handleMap entry
+ *
+ * @property callbackObj - Callback object, this must implement the callback interface.
+ * @property {string} stackTrace - Stack trace from when the callback object was registered. This is used to proved extra context when debugging leaked callback objects.
+ */
+class UniFFICallbackHandleMapEntry {
+ constructor(callbackObj, stackTrace) {
+ this.callbackObj = callbackObj;
+ this.stackTrace = stackTrace
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterI32 extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (!Number.isInteger(value)) {
+ throw new UniFFITypeError(`${value} is not an integer`);
+ }
+ if (value < -2147483648 || value > 2147483647) {
+ throw new UniFFITypeError(`${value} exceeds the I32 bounds`);
+ }
+ }
+ static computeSize() {
+ return 4;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeInt32(value)
+ }
+ static read(dataStream) {
+ return dataStream.readInt32()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterString extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (typeof value !== "string") {
+ throw new UniFFITypeError(`${value} is not a string`);
+ }
+ }
+
+ static lift(buf) {
+ const decoder = new TextDecoder();
+ const utf8Arr = new Uint8Array(buf);
+ return decoder.decode(utf8Arr);
+ }
+ static lower(value) {
+ const encoder = new TextEncoder();
+ return encoder.encode(value).buffer;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeString(value);
+ }
+
+ static read(dataStream) {
+ return dataStream.readString();
+ }
+
+ static computeSize(value) {
+ const encoder = new TextEncoder();
+ return 4 + encoder.encode(value).length
+ }
+}
+
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeLogger extends FfiConverter {
+ static lower(callbackObj) {
+ return callbackHandlerLogger.storeCallbackObj(callbackObj)
+ }
+
+ static lift(handleId) {
+ return callbackHandlerLogger.getCallbackObj(handleId)
+ }
+
+ static read(dataStream) {
+ return this.lift(dataStream.readInt64())
+ }
+
+ static write(dataStream, callbackObj) {
+ dataStream.writeInt64(this.lower(callbackObj))
+ }
+
+ static computeSize(callbackObj) {
+ return 8;
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterSequencei32 extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ const len = dataStream.readInt32();
+ const arr = [];
+ for (let i = 0; i < len; i++) {
+ arr.push(FfiConverterI32.read(dataStream));
+ }
+ return arr;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeInt32(value.length);
+ value.forEach((innerValue) => {
+ FfiConverterI32.write(dataStream, innerValue);
+ })
+ }
+
+ static computeSize(value) {
+ // The size of the length
+ let size = 4;
+ for (const innerValue of value) {
+ size += FfiConverterI32.computeSize(innerValue);
+ }
+ return size;
+ }
+
+ static checkType(value) {
+ if (!Array.isArray(value)) {
+ throw new UniFFITypeError(`${value} is not an array`);
+ }
+ value.forEach((innerValue, idx) => {
+ try {
+ FfiConverterI32.checkType(innerValue);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(`[${idx}]`);
+ }
+ throw e;
+ }
+ })
+ }
+}
+
+
+// Define callback interface handlers, this must come after the type loop since they reference the FfiConverters defined above.
+
+const callbackHandlerLogger = new UniFFICallbackHandler(
+ "fixture_callbacks:Logger",
+ 0,
+ [
+ new UniFFICallbackMethodHandler(
+ "log",
+ [
+ FfiConverterString,
+ ],
+ ),
+ new UniFFICallbackMethodHandler(
+ "finished",
+ [
+ ],
+ ),
+ ]
+);
+
+// Allow the shutdown-related functionality to be tested in the unit tests
+UnitTestObjs.callbackHandlerLogger = callbackHandlerLogger;
+
+
+
+
+
+export function logEvenNumbers(logger,items) {
+
+ const liftResult = (result) => undefined;
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypeLogger.checkType(logger)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("logger");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterSequencei32.checkType(items)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("items");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 42, // fixture_callbacks:uniffi_uniffi_fixture_callbacks_fn_func_log_even_numbers
+ FfiConverterTypeLogger.lower(logger),
+ FfiConverterSequencei32.lower(items),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
+
+export function logEvenNumbersMainThread(logger,items) {
+
+ const liftResult = (result) => undefined;
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypeLogger.checkType(logger)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("logger");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterSequencei32.checkType(items)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("items");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callSync(
+ 43, // fixture_callbacks:uniffi_uniffi_fixture_callbacks_fn_func_log_even_numbers_main_thread
+ FfiConverterTypeLogger.lower(logger),
+ FfiConverterSequencei32.lower(items),
+ )
+ }
+ return handleRustResult(functionCall(), liftResult, liftError);
+}
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustGeometry.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustGeometry.sys.mjs
new file mode 100644
index 0000000000..1a7ebb287a
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustGeometry.sys.mjs
@@ -0,0 +1,520 @@
+// This file was autogenerated by the `uniffi-bindgen-gecko-js` crate.
+// Trust me, you don't want to mess with it!
+
+import { UniFFITypeError } from "resource://gre/modules/UniFFI.sys.mjs";
+
+
+
+// Objects intended to be used in the unit tests
+export var UnitTestObjs = {};
+
+// Write/Read data to/from an ArrayBuffer
+class ArrayBufferDataStream {
+ constructor(arrayBuffer) {
+ this.dataView = new DataView(arrayBuffer);
+ this.pos = 0;
+ }
+
+ readUint8() {
+ let rv = this.dataView.getUint8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeUint8(value) {
+ this.dataView.setUint8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readUint16() {
+ let rv = this.dataView.getUint16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeUint16(value) {
+ this.dataView.setUint16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readUint32() {
+ let rv = this.dataView.getUint32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeUint32(value) {
+ this.dataView.setUint32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readUint64() {
+ let rv = this.dataView.getBigUint64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeUint64(value) {
+ this.dataView.setBigUint64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+
+ readInt8() {
+ let rv = this.dataView.getInt8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeInt8(value) {
+ this.dataView.setInt8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readInt16() {
+ let rv = this.dataView.getInt16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeInt16(value) {
+ this.dataView.setInt16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readInt32() {
+ let rv = this.dataView.getInt32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeInt32(value) {
+ this.dataView.setInt32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readInt64() {
+ let rv = this.dataView.getBigInt64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeInt64(value) {
+ this.dataView.setBigInt64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+ readFloat32() {
+ let rv = this.dataView.getFloat32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeFloat32(value) {
+ this.dataView.setFloat32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readFloat64() {
+ let rv = this.dataView.getFloat64(this.pos);
+ this.pos += 8;
+ return rv;
+ }
+
+ writeFloat64(value) {
+ this.dataView.setFloat64(this.pos, value);
+ this.pos += 8;
+ }
+
+
+ writeString(value) {
+ const encoder = new TextEncoder();
+ // Note: in order to efficiently write this data, we first write the
+ // string data, reserving 4 bytes for the size.
+ const dest = new Uint8Array(this.dataView.buffer, this.pos + 4);
+ const encodeResult = encoder.encodeInto(value, dest);
+ if (encodeResult.read != value.length) {
+ throw new UniFFIError(
+ "writeString: out of space when writing to ArrayBuffer. Did the computeSize() method returned the wrong result?"
+ );
+ }
+ const size = encodeResult.written;
+ // Next, go back and write the size before the string data
+ this.dataView.setUint32(this.pos, size);
+ // Finally, advance our position past both the size and string data
+ this.pos += size + 4;
+ }
+
+ readString() {
+ const decoder = new TextDecoder();
+ const size = this.readUint32();
+ const source = new Uint8Array(this.dataView.buffer, this.pos, size)
+ const value = decoder.decode(source);
+ this.pos += size;
+ return value;
+ }
+}
+
+function handleRustResult(result, liftCallback, liftErrCallback) {
+ switch (result.code) {
+ case "success":
+ return liftCallback(result.data);
+
+ case "error":
+ throw liftErrCallback(result.data);
+
+ case "internal-error":
+ let message = result.internalErrorMessage;
+ if (message) {
+ throw new UniFFIInternalError(message);
+ } else {
+ throw new UniFFIInternalError("Unknown error");
+ }
+
+ default:
+ throw new UniFFIError(`Unexpected status code: ${result.code}`);
+ }
+}
+
+class UniFFIError {
+ constructor(message) {
+ this.message = message;
+ }
+
+ toString() {
+ return `UniFFIError: ${this.message}`
+ }
+}
+
+class UniFFIInternalError extends UniFFIError {}
+
+// Base class for FFI converters
+class FfiConverter {
+ // throw `UniFFITypeError` if a value to be converted has an invalid type
+ static checkType(value) {
+ if (value === undefined ) {
+ throw new UniFFITypeError(`undefined`);
+ }
+ if (value === null ) {
+ throw new UniFFITypeError(`null`);
+ }
+ }
+}
+
+// Base class for FFI converters that lift/lower by reading/writing to an ArrayBuffer
+class FfiConverterArrayBuffer extends FfiConverter {
+ static lift(buf) {
+ return this.read(new ArrayBufferDataStream(buf));
+ }
+
+ static lower(value) {
+ const buf = new ArrayBuffer(this.computeSize(value));
+ const dataStream = new ArrayBufferDataStream(buf);
+ this.write(dataStream, value);
+ return buf;
+ }
+}
+
+// Symbols that are used to ensure that Object constructors
+// can only be used with a proper UniFFI pointer
+const uniffiObjectPtr = Symbol("uniffiObjectPtr");
+const constructUniffiObject = Symbol("constructUniffiObject");
+UnitTestObjs.uniffiObjectPtr = uniffiObjectPtr;
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterF64 extends FfiConverter {
+ static computeSize() {
+ return 8;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeFloat64(value)
+ }
+ static read(dataStream) {
+ return dataStream.readFloat64()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterString extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (typeof value !== "string") {
+ throw new UniFFITypeError(`${value} is not a string`);
+ }
+ }
+
+ static lift(buf) {
+ const decoder = new TextDecoder();
+ const utf8Arr = new Uint8Array(buf);
+ return decoder.decode(utf8Arr);
+ }
+ static lower(value) {
+ const encoder = new TextEncoder();
+ return encoder.encode(value).buffer;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeString(value);
+ }
+
+ static read(dataStream) {
+ return dataStream.readString();
+ }
+
+ static computeSize(value) {
+ const encoder = new TextEncoder();
+ return 4 + encoder.encode(value).length
+ }
+}
+
+export class Line {
+ constructor({ start, end } = {}) {
+ try {
+ FfiConverterTypePoint.checkType(start)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("start");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterTypePoint.checkType(end)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("end");
+ }
+ throw e;
+ }
+ this.start = start;
+ this.end = end;
+ }
+ equals(other) {
+ return (
+ this.start.equals(other.start) &&
+ this.end.equals(other.end)
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeLine extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new Line({
+ start: FfiConverterTypePoint.read(dataStream),
+ end: FfiConverterTypePoint.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterTypePoint.write(dataStream, value.start);
+ FfiConverterTypePoint.write(dataStream, value.end);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterTypePoint.computeSize(value.start);
+ totalSize += FfiConverterTypePoint.computeSize(value.end);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof Line)) {
+ throw new TypeError(`Expected 'Line', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterTypePoint.checkType(value.start);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".start");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterTypePoint.checkType(value.end);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".end");
+ }
+ throw e;
+ }
+ }
+}
+
+export class Point {
+ constructor({ coordX, coordY } = {}) {
+ try {
+ FfiConverterF64.checkType(coordX)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("coordX");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterF64.checkType(coordY)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("coordY");
+ }
+ throw e;
+ }
+ this.coordX = coordX;
+ this.coordY = coordY;
+ }
+ equals(other) {
+ return (
+ this.coordX == other.coordX &&
+ this.coordY == other.coordY
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypePoint extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new Point({
+ coordX: FfiConverterF64.read(dataStream),
+ coordY: FfiConverterF64.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterF64.write(dataStream, value.coordX);
+ FfiConverterF64.write(dataStream, value.coordY);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterF64.computeSize(value.coordX);
+ totalSize += FfiConverterF64.computeSize(value.coordY);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof Point)) {
+ throw new TypeError(`Expected 'Point', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterF64.checkType(value.coordX);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".coordX");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterF64.checkType(value.coordY);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".coordY");
+ }
+ throw e;
+ }
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterOptionalTypePoint extends FfiConverterArrayBuffer {
+ static checkType(value) {
+ if (value !== undefined && value !== null) {
+ FfiConverterTypePoint.checkType(value)
+ }
+ }
+
+ static read(dataStream) {
+ const code = dataStream.readUint8(0);
+ switch (code) {
+ case 0:
+ return null
+ case 1:
+ return FfiConverterTypePoint.read(dataStream)
+ default:
+ throw UniFFIError(`Unexpected code: ${code}`);
+ }
+ }
+
+ static write(dataStream, value) {
+ if (value === null || value === undefined) {
+ dataStream.writeUint8(0);
+ return;
+ }
+ dataStream.writeUint8(1);
+ FfiConverterTypePoint.write(dataStream, value)
+ }
+
+ static computeSize(value) {
+ if (value === null || value === undefined) {
+ return 1;
+ }
+ return 1 + FfiConverterTypePoint.computeSize(value)
+ }
+}
+
+
+
+
+
+export function gradient(ln) {
+
+ const liftResult = (result) => FfiConverterF64.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypeLine.checkType(ln)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("ln");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 44, // geometry:uniffi_uniffi_geometry_fn_func_gradient
+ FfiConverterTypeLine.lower(ln),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
+
+export function intersection(ln1,ln2) {
+
+ const liftResult = (result) => FfiConverterOptionalTypePoint.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypeLine.checkType(ln1)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("ln1");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterTypeLine.checkType(ln2)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("ln2");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 45, // geometry:uniffi_uniffi_geometry_fn_func_intersection
+ FfiConverterTypeLine.lower(ln1),
+ FfiConverterTypeLine.lower(ln2),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustRondpoint.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustRondpoint.sys.mjs
new file mode 100644
index 0000000000..1edb7ec608
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustRondpoint.sys.mjs
@@ -0,0 +1,3384 @@
+// This file was autogenerated by the `uniffi-bindgen-gecko-js` crate.
+// Trust me, you don't want to mess with it!
+
+import { UniFFITypeError } from "resource://gre/modules/UniFFI.sys.mjs";
+
+
+
+// Objects intended to be used in the unit tests
+export var UnitTestObjs = {};
+
+// Write/Read data to/from an ArrayBuffer
+class ArrayBufferDataStream {
+ constructor(arrayBuffer) {
+ this.dataView = new DataView(arrayBuffer);
+ this.pos = 0;
+ }
+
+ readUint8() {
+ let rv = this.dataView.getUint8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeUint8(value) {
+ this.dataView.setUint8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readUint16() {
+ let rv = this.dataView.getUint16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeUint16(value) {
+ this.dataView.setUint16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readUint32() {
+ let rv = this.dataView.getUint32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeUint32(value) {
+ this.dataView.setUint32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readUint64() {
+ let rv = this.dataView.getBigUint64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeUint64(value) {
+ this.dataView.setBigUint64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+
+ readInt8() {
+ let rv = this.dataView.getInt8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeInt8(value) {
+ this.dataView.setInt8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readInt16() {
+ let rv = this.dataView.getInt16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeInt16(value) {
+ this.dataView.setInt16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readInt32() {
+ let rv = this.dataView.getInt32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeInt32(value) {
+ this.dataView.setInt32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readInt64() {
+ let rv = this.dataView.getBigInt64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeInt64(value) {
+ this.dataView.setBigInt64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+ readFloat32() {
+ let rv = this.dataView.getFloat32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeFloat32(value) {
+ this.dataView.setFloat32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readFloat64() {
+ let rv = this.dataView.getFloat64(this.pos);
+ this.pos += 8;
+ return rv;
+ }
+
+ writeFloat64(value) {
+ this.dataView.setFloat64(this.pos, value);
+ this.pos += 8;
+ }
+
+
+ writeString(value) {
+ const encoder = new TextEncoder();
+ // Note: in order to efficiently write this data, we first write the
+ // string data, reserving 4 bytes for the size.
+ const dest = new Uint8Array(this.dataView.buffer, this.pos + 4);
+ const encodeResult = encoder.encodeInto(value, dest);
+ if (encodeResult.read != value.length) {
+ throw new UniFFIError(
+ "writeString: out of space when writing to ArrayBuffer. Did the computeSize() method returned the wrong result?"
+ );
+ }
+ const size = encodeResult.written;
+ // Next, go back and write the size before the string data
+ this.dataView.setUint32(this.pos, size);
+ // Finally, advance our position past both the size and string data
+ this.pos += size + 4;
+ }
+
+ readString() {
+ const decoder = new TextDecoder();
+ const size = this.readUint32();
+ const source = new Uint8Array(this.dataView.buffer, this.pos, size)
+ const value = decoder.decode(source);
+ this.pos += size;
+ return value;
+ }
+
+ // Reads a Optionneur pointer from the data stream
+ // UniFFI Pointers are **always** 8 bytes long. That is enforced
+ // by the C++ and Rust Scaffolding code.
+ readPointerOptionneur() {
+ const pointerId = 5; // rondpoint:Optionneur
+ const res = UniFFIScaffolding.readPointer(pointerId, this.dataView.buffer, this.pos);
+ this.pos += 8;
+ return res;
+ }
+
+ // Writes a Optionneur pointer into the data stream
+ // UniFFI Pointers are **always** 8 bytes long. That is enforced
+ // by the C++ and Rust Scaffolding code.
+ writePointerOptionneur(value) {
+ const pointerId = 5; // rondpoint:Optionneur
+ UniFFIScaffolding.writePointer(pointerId, value, this.dataView.buffer, this.pos);
+ this.pos += 8;
+ }
+
+
+ // Reads a Retourneur pointer from the data stream
+ // UniFFI Pointers are **always** 8 bytes long. That is enforced
+ // by the C++ and Rust Scaffolding code.
+ readPointerRetourneur() {
+ const pointerId = 6; // rondpoint:Retourneur
+ const res = UniFFIScaffolding.readPointer(pointerId, this.dataView.buffer, this.pos);
+ this.pos += 8;
+ return res;
+ }
+
+ // Writes a Retourneur pointer into the data stream
+ // UniFFI Pointers are **always** 8 bytes long. That is enforced
+ // by the C++ and Rust Scaffolding code.
+ writePointerRetourneur(value) {
+ const pointerId = 6; // rondpoint:Retourneur
+ UniFFIScaffolding.writePointer(pointerId, value, this.dataView.buffer, this.pos);
+ this.pos += 8;
+ }
+
+
+ // Reads a Stringifier pointer from the data stream
+ // UniFFI Pointers are **always** 8 bytes long. That is enforced
+ // by the C++ and Rust Scaffolding code.
+ readPointerStringifier() {
+ const pointerId = 7; // rondpoint:Stringifier
+ const res = UniFFIScaffolding.readPointer(pointerId, this.dataView.buffer, this.pos);
+ this.pos += 8;
+ return res;
+ }
+
+ // Writes a Stringifier pointer into the data stream
+ // UniFFI Pointers are **always** 8 bytes long. That is enforced
+ // by the C++ and Rust Scaffolding code.
+ writePointerStringifier(value) {
+ const pointerId = 7; // rondpoint:Stringifier
+ UniFFIScaffolding.writePointer(pointerId, value, this.dataView.buffer, this.pos);
+ this.pos += 8;
+ }
+
+}
+
+function handleRustResult(result, liftCallback, liftErrCallback) {
+ switch (result.code) {
+ case "success":
+ return liftCallback(result.data);
+
+ case "error":
+ throw liftErrCallback(result.data);
+
+ case "internal-error":
+ let message = result.internalErrorMessage;
+ if (message) {
+ throw new UniFFIInternalError(message);
+ } else {
+ throw new UniFFIInternalError("Unknown error");
+ }
+
+ default:
+ throw new UniFFIError(`Unexpected status code: ${result.code}`);
+ }
+}
+
+class UniFFIError {
+ constructor(message) {
+ this.message = message;
+ }
+
+ toString() {
+ return `UniFFIError: ${this.message}`
+ }
+}
+
+class UniFFIInternalError extends UniFFIError {}
+
+// Base class for FFI converters
+class FfiConverter {
+ // throw `UniFFITypeError` if a value to be converted has an invalid type
+ static checkType(value) {
+ if (value === undefined ) {
+ throw new UniFFITypeError(`undefined`);
+ }
+ if (value === null ) {
+ throw new UniFFITypeError(`null`);
+ }
+ }
+}
+
+// Base class for FFI converters that lift/lower by reading/writing to an ArrayBuffer
+class FfiConverterArrayBuffer extends FfiConverter {
+ static lift(buf) {
+ return this.read(new ArrayBufferDataStream(buf));
+ }
+
+ static lower(value) {
+ const buf = new ArrayBuffer(this.computeSize(value));
+ const dataStream = new ArrayBufferDataStream(buf);
+ this.write(dataStream, value);
+ return buf;
+ }
+}
+
+// Symbols that are used to ensure that Object constructors
+// can only be used with a proper UniFFI pointer
+const uniffiObjectPtr = Symbol("uniffiObjectPtr");
+const constructUniffiObject = Symbol("constructUniffiObject");
+UnitTestObjs.uniffiObjectPtr = uniffiObjectPtr;
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterU8 extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (!Number.isInteger(value)) {
+ throw new UniFFITypeError(`${value} is not an integer`);
+ }
+ if (value < 0 || value > 256) {
+ throw new UniFFITypeError(`${value} exceeds the U8 bounds`);
+ }
+ }
+ static computeSize() {
+ return 1;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeUint8(value)
+ }
+ static read(dataStream) {
+ return dataStream.readUint8()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterI8 extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (!Number.isInteger(value)) {
+ throw new UniFFITypeError(`${value} is not an integer`);
+ }
+ if (value < -128 || value > 127) {
+ throw new UniFFITypeError(`${value} exceeds the I8 bounds`);
+ }
+ }
+ static computeSize() {
+ return 1;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeInt8(value)
+ }
+ static read(dataStream) {
+ return dataStream.readInt8()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterU16 extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (!Number.isInteger(value)) {
+ throw new UniFFITypeError(`${value} is not an integer`);
+ }
+ if (value < 0 || value > 65535) {
+ throw new UniFFITypeError(`${value} exceeds the U16 bounds`);
+ }
+ }
+ static computeSize() {
+ return 2;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeUint16(value)
+ }
+ static read(dataStream) {
+ return dataStream.readUint16()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterI16 extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (!Number.isInteger(value)) {
+ throw new UniFFITypeError(`${value} is not an integer`);
+ }
+ if (value < -32768 || value > 32767) {
+ throw new UniFFITypeError(`${value} exceeds the I16 bounds`);
+ }
+ }
+ static computeSize() {
+ return 2;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeInt16(value)
+ }
+ static read(dataStream) {
+ return dataStream.readInt16()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterU32 extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (!Number.isInteger(value)) {
+ throw new UniFFITypeError(`${value} is not an integer`);
+ }
+ if (value < 0 || value > 4294967295) {
+ throw new UniFFITypeError(`${value} exceeds the U32 bounds`);
+ }
+ }
+ static computeSize() {
+ return 4;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeUint32(value)
+ }
+ static read(dataStream) {
+ return dataStream.readUint32()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterI32 extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (!Number.isInteger(value)) {
+ throw new UniFFITypeError(`${value} is not an integer`);
+ }
+ if (value < -2147483648 || value > 2147483647) {
+ throw new UniFFITypeError(`${value} exceeds the I32 bounds`);
+ }
+ }
+ static computeSize() {
+ return 4;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeInt32(value)
+ }
+ static read(dataStream) {
+ return dataStream.readInt32()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterU64 extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (!Number.isSafeInteger(value)) {
+ throw new UniFFITypeError(`${value} exceeds the safe integer bounds`);
+ }
+ if (value < 0) {
+ throw new UniFFITypeError(`${value} exceeds the U64 bounds`);
+ }
+ }
+ static computeSize() {
+ return 8;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeUint64(value)
+ }
+ static read(dataStream) {
+ return dataStream.readUint64()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterI64 extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (!Number.isSafeInteger(value)) {
+ throw new UniFFITypeError(`${value} exceeds the safe integer bounds`);
+ }
+ }
+ static computeSize() {
+ return 8;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeInt64(value)
+ }
+ static read(dataStream) {
+ return dataStream.readInt64()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterF32 extends FfiConverter {
+ static computeSize() {
+ return 4;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeFloat32(value)
+ }
+ static read(dataStream) {
+ return dataStream.readFloat32()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterF64 extends FfiConverter {
+ static computeSize() {
+ return 8;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeFloat64(value)
+ }
+ static read(dataStream) {
+ return dataStream.readFloat64()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterBool extends FfiConverter {
+ static computeSize() {
+ return 1;
+ }
+ static lift(value) {
+ return value == 1;
+ }
+ static lower(value) {
+ if (value) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ static write(dataStream, value) {
+ dataStream.writeUint8(this.lower(value))
+ }
+ static read(dataStream) {
+ return this.lift(dataStream.readUint8())
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterString extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (typeof value !== "string") {
+ throw new UniFFITypeError(`${value} is not a string`);
+ }
+ }
+
+ static lift(buf) {
+ const decoder = new TextDecoder();
+ const utf8Arr = new Uint8Array(buf);
+ return decoder.decode(utf8Arr);
+ }
+ static lower(value) {
+ const encoder = new TextEncoder();
+ return encoder.encode(value).buffer;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeString(value);
+ }
+
+ static read(dataStream) {
+ return dataStream.readString();
+ }
+
+ static computeSize(value) {
+ const encoder = new TextEncoder();
+ return 4 + encoder.encode(value).length
+ }
+}
+
+export class Optionneur {
+ // Use `init` to instantiate this class.
+ // DO NOT USE THIS CONSTRUCTOR DIRECTLY
+ constructor(opts) {
+ if (!Object.prototype.hasOwnProperty.call(opts, constructUniffiObject)) {
+ throw new UniFFIError("Attempting to construct an object using the JavaScript constructor directly" +
+ "Please use a UDL defined constructor, or the init function for the primary constructor")
+ }
+ if (!opts[constructUniffiObject] instanceof UniFFIPointer) {
+ throw new UniFFIError("Attempting to create a UniFFI object with a pointer that is not an instance of UniFFIPointer")
+ }
+ this[uniffiObjectPtr] = opts[constructUniffiObject];
+ }
+ /**
+ * An async constructor for Optionneur.
+ *
+ * @returns {Promise<Optionneur>}: A promise that resolves
+ * to a newly constructed Optionneur
+ */
+ static init() {
+ const liftResult = (result) => FfiConverterTypeOptionneur.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ return UniFFIScaffolding.callAsync(
+ 46, // rondpoint:uniffi_uniffi_rondpoint_fn_constructor_optionneur_new
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }}
+
+ sinonBoolean(value = false) {
+ const liftResult = (result) => FfiConverterBool.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterBool.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 47, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_boolean
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterBool.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonEnum(value = Enumeration.TROIS) {
+ const liftResult = (result) => FfiConverterTypeEnumeration.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypeEnumeration.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 48, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_enum
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterTypeEnumeration.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonF32(value = 42.0) {
+ const liftResult = (result) => FfiConverterF32.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterF32.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 49, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_f32
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterF32.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonF64(value = 42.1) {
+ const liftResult = (result) => FfiConverterF64.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterF64.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 50, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_f64
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterF64.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonI16Dec(value = 42) {
+ const liftResult = (result) => FfiConverterI16.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI16.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 51, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i16_dec
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterI16.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonI16Hex(value = 0x7f) {
+ const liftResult = (result) => FfiConverterI16.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI16.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 52, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i16_hex
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterI16.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonI32Dec(value = 42) {
+ const liftResult = (result) => FfiConverterI32.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI32.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 53, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i32_dec
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterI32.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonI32Hex(value = 0x7fffffff) {
+ const liftResult = (result) => FfiConverterI32.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI32.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 54, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i32_hex
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterI32.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonI64Dec(value = 42) {
+ const liftResult = (result) => FfiConverterI64.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI64.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 55, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i64_dec
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterI64.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonI64Hex(value = 0x7fffffffffffffff) {
+ const liftResult = (result) => FfiConverterI64.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI64.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 56, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i64_hex
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterI64.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonI8Dec(value = -42) {
+ const liftResult = (result) => FfiConverterI8.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI8.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 57, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i8_dec
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterI8.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonI8Hex(value = -127) {
+ const liftResult = (result) => FfiConverterI8.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI8.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 58, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_i8_hex
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterI8.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonNull(value = null) {
+ const liftResult = (result) => FfiConverterOptionalstring.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterOptionalstring.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 59, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_null
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterOptionalstring.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonSequence(value = []) {
+ const liftResult = (result) => FfiConverterSequencestring.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterSequencestring.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 60, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_sequence
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterSequencestring.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonString(value = "default") {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterString.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 61, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_string
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterString.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonU16Dec(value = 42) {
+ const liftResult = (result) => FfiConverterU16.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU16.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 62, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u16_dec
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterU16.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonU16Hex(value = 0xffff) {
+ const liftResult = (result) => FfiConverterU16.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU16.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 63, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u16_hex
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterU16.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonU32Dec(value = 42) {
+ const liftResult = (result) => FfiConverterU32.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU32.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 64, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u32_dec
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterU32.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonU32Hex(value = 0xffffffff) {
+ const liftResult = (result) => FfiConverterU32.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU32.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 65, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u32_hex
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterU32.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonU32Oct(value = 0o755) {
+ const liftResult = (result) => FfiConverterU32.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU32.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 66, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u32_oct
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterU32.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonU64Dec(value = 42) {
+ const liftResult = (result) => FfiConverterU64.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU64.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 67, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u64_dec
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterU64.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonU64Hex(value = 0xffffffffffffffff) {
+ const liftResult = (result) => FfiConverterU64.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU64.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 68, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u64_hex
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterU64.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonU8Dec(value = 42) {
+ const liftResult = (result) => FfiConverterU8.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU8.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 69, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u8_dec
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterU8.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonU8Hex(value = 0xff) {
+ const liftResult = (result) => FfiConverterU8.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU8.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 70, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_u8_hex
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterU8.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ sinonZero(value = 0) {
+ const liftResult = (result) => FfiConverterOptionali32.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterOptionali32.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 71, // rondpoint:uniffi_uniffi_rondpoint_fn_method_optionneur_sinon_zero
+ FfiConverterTypeOptionneur.lower(this),
+ FfiConverterOptionali32.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeOptionneur extends FfiConverter {
+ static lift(value) {
+ const opts = {};
+ opts[constructUniffiObject] = value;
+ return new Optionneur(opts);
+ }
+
+ static lower(value) {
+ return value[uniffiObjectPtr];
+ }
+
+ static read(dataStream) {
+ return this.lift(dataStream.readPointerOptionneur());
+ }
+
+ static write(dataStream, value) {
+ dataStream.writePointerOptionneur(value[uniffiObjectPtr]);
+ }
+
+ static computeSize(value) {
+ return 8;
+ }
+}
+
+export class Retourneur {
+ // Use `init` to instantiate this class.
+ // DO NOT USE THIS CONSTRUCTOR DIRECTLY
+ constructor(opts) {
+ if (!Object.prototype.hasOwnProperty.call(opts, constructUniffiObject)) {
+ throw new UniFFIError("Attempting to construct an object using the JavaScript constructor directly" +
+ "Please use a UDL defined constructor, or the init function for the primary constructor")
+ }
+ if (!opts[constructUniffiObject] instanceof UniFFIPointer) {
+ throw new UniFFIError("Attempting to create a UniFFI object with a pointer that is not an instance of UniFFIPointer")
+ }
+ this[uniffiObjectPtr] = opts[constructUniffiObject];
+ }
+ /**
+ * An async constructor for Retourneur.
+ *
+ * @returns {Promise<Retourneur>}: A promise that resolves
+ * to a newly constructed Retourneur
+ */
+ static init() {
+ const liftResult = (result) => FfiConverterTypeRetourneur.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ return UniFFIScaffolding.callAsync(
+ 72, // rondpoint:uniffi_uniffi_rondpoint_fn_constructor_retourneur_new
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }}
+
+ identiqueBoolean(value) {
+ const liftResult = (result) => FfiConverterBool.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterBool.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 73, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_boolean
+ FfiConverterTypeRetourneur.lower(this),
+ FfiConverterBool.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ identiqueDouble(value) {
+ const liftResult = (result) => FfiConverterF64.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterF64.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 74, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_double
+ FfiConverterTypeRetourneur.lower(this),
+ FfiConverterF64.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ identiqueFloat(value) {
+ const liftResult = (result) => FfiConverterF32.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterF32.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 75, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_float
+ FfiConverterTypeRetourneur.lower(this),
+ FfiConverterF32.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ identiqueI16(value) {
+ const liftResult = (result) => FfiConverterI16.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI16.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 76, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i16
+ FfiConverterTypeRetourneur.lower(this),
+ FfiConverterI16.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ identiqueI32(value) {
+ const liftResult = (result) => FfiConverterI32.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI32.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 77, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i32
+ FfiConverterTypeRetourneur.lower(this),
+ FfiConverterI32.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ identiqueI64(value) {
+ const liftResult = (result) => FfiConverterI64.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI64.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 78, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i64
+ FfiConverterTypeRetourneur.lower(this),
+ FfiConverterI64.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ identiqueI8(value) {
+ const liftResult = (result) => FfiConverterI8.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI8.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 79, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_i8
+ FfiConverterTypeRetourneur.lower(this),
+ FfiConverterI8.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ identiqueNombres(value) {
+ const liftResult = (result) => FfiConverterTypeDictionnaireNombres.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypeDictionnaireNombres.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 80, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_nombres
+ FfiConverterTypeRetourneur.lower(this),
+ FfiConverterTypeDictionnaireNombres.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ identiqueNombresSignes(value) {
+ const liftResult = (result) => FfiConverterTypeDictionnaireNombresSignes.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypeDictionnaireNombresSignes.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 81, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_nombres_signes
+ FfiConverterTypeRetourneur.lower(this),
+ FfiConverterTypeDictionnaireNombresSignes.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ identiqueOptionneurDictionnaire(value) {
+ const liftResult = (result) => FfiConverterTypeOptionneurDictionnaire.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypeOptionneurDictionnaire.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 82, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_optionneur_dictionnaire
+ FfiConverterTypeRetourneur.lower(this),
+ FfiConverterTypeOptionneurDictionnaire.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ identiqueString(value) {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterString.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 83, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_string
+ FfiConverterTypeRetourneur.lower(this),
+ FfiConverterString.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ identiqueU16(value) {
+ const liftResult = (result) => FfiConverterU16.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU16.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 84, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u16
+ FfiConverterTypeRetourneur.lower(this),
+ FfiConverterU16.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ identiqueU32(value) {
+ const liftResult = (result) => FfiConverterU32.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU32.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 85, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u32
+ FfiConverterTypeRetourneur.lower(this),
+ FfiConverterU32.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ identiqueU64(value) {
+ const liftResult = (result) => FfiConverterU64.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU64.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 86, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u64
+ FfiConverterTypeRetourneur.lower(this),
+ FfiConverterU64.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ identiqueU8(value) {
+ const liftResult = (result) => FfiConverterU8.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU8.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 87, // rondpoint:uniffi_uniffi_rondpoint_fn_method_retourneur_identique_u8
+ FfiConverterTypeRetourneur.lower(this),
+ FfiConverterU8.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeRetourneur extends FfiConverter {
+ static lift(value) {
+ const opts = {};
+ opts[constructUniffiObject] = value;
+ return new Retourneur(opts);
+ }
+
+ static lower(value) {
+ return value[uniffiObjectPtr];
+ }
+
+ static read(dataStream) {
+ return this.lift(dataStream.readPointerRetourneur());
+ }
+
+ static write(dataStream, value) {
+ dataStream.writePointerRetourneur(value[uniffiObjectPtr]);
+ }
+
+ static computeSize(value) {
+ return 8;
+ }
+}
+
+export class Stringifier {
+ // Use `init` to instantiate this class.
+ // DO NOT USE THIS CONSTRUCTOR DIRECTLY
+ constructor(opts) {
+ if (!Object.prototype.hasOwnProperty.call(opts, constructUniffiObject)) {
+ throw new UniFFIError("Attempting to construct an object using the JavaScript constructor directly" +
+ "Please use a UDL defined constructor, or the init function for the primary constructor")
+ }
+ if (!opts[constructUniffiObject] instanceof UniFFIPointer) {
+ throw new UniFFIError("Attempting to create a UniFFI object with a pointer that is not an instance of UniFFIPointer")
+ }
+ this[uniffiObjectPtr] = opts[constructUniffiObject];
+ }
+ /**
+ * An async constructor for Stringifier.
+ *
+ * @returns {Promise<Stringifier>}: A promise that resolves
+ * to a newly constructed Stringifier
+ */
+ static init() {
+ const liftResult = (result) => FfiConverterTypeStringifier.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ return UniFFIScaffolding.callAsync(
+ 88, // rondpoint:uniffi_uniffi_rondpoint_fn_constructor_stringifier_new
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }}
+
+ toStringBoolean(value) {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterBool.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 89, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_boolean
+ FfiConverterTypeStringifier.lower(this),
+ FfiConverterBool.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ toStringDouble(value) {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterF64.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 90, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_double
+ FfiConverterTypeStringifier.lower(this),
+ FfiConverterF64.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ toStringFloat(value) {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterF32.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 91, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_float
+ FfiConverterTypeStringifier.lower(this),
+ FfiConverterF32.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ toStringI16(value) {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI16.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 92, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i16
+ FfiConverterTypeStringifier.lower(this),
+ FfiConverterI16.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ toStringI32(value) {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI32.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 93, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i32
+ FfiConverterTypeStringifier.lower(this),
+ FfiConverterI32.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ toStringI64(value) {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI64.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 94, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i64
+ FfiConverterTypeStringifier.lower(this),
+ FfiConverterI64.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ toStringI8(value) {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterI8.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 95, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_i8
+ FfiConverterTypeStringifier.lower(this),
+ FfiConverterI8.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ toStringU16(value) {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU16.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 96, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u16
+ FfiConverterTypeStringifier.lower(this),
+ FfiConverterU16.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ toStringU32(value) {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU32.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 97, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u32
+ FfiConverterTypeStringifier.lower(this),
+ FfiConverterU32.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ toStringU64(value) {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU64.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 98, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u64
+ FfiConverterTypeStringifier.lower(this),
+ FfiConverterU64.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ toStringU8(value) {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterU8.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 99, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_to_string_u8
+ FfiConverterTypeStringifier.lower(this),
+ FfiConverterU8.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ wellKnownString(value) {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterString.checkType(value)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("value");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 100, // rondpoint:uniffi_uniffi_rondpoint_fn_method_stringifier_well_known_string
+ FfiConverterTypeStringifier.lower(this),
+ FfiConverterString.lower(value),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeStringifier extends FfiConverter {
+ static lift(value) {
+ const opts = {};
+ opts[constructUniffiObject] = value;
+ return new Stringifier(opts);
+ }
+
+ static lower(value) {
+ return value[uniffiObjectPtr];
+ }
+
+ static read(dataStream) {
+ return this.lift(dataStream.readPointerStringifier());
+ }
+
+ static write(dataStream, value) {
+ dataStream.writePointerStringifier(value[uniffiObjectPtr]);
+ }
+
+ static computeSize(value) {
+ return 8;
+ }
+}
+
+export class Dictionnaire {
+ constructor({ un, deux, petitNombre, grosNombre } = {}) {
+ try {
+ FfiConverterTypeEnumeration.checkType(un)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("un");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterBool.checkType(deux)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("deux");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU8.checkType(petitNombre)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("petitNombre");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU64.checkType(grosNombre)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("grosNombre");
+ }
+ throw e;
+ }
+ this.un = un;
+ this.deux = deux;
+ this.petitNombre = petitNombre;
+ this.grosNombre = grosNombre;
+ }
+ equals(other) {
+ return (
+ this.un == other.un &&
+ this.deux == other.deux &&
+ this.petitNombre == other.petitNombre &&
+ this.grosNombre == other.grosNombre
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeDictionnaire extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new Dictionnaire({
+ un: FfiConverterTypeEnumeration.read(dataStream),
+ deux: FfiConverterBool.read(dataStream),
+ petitNombre: FfiConverterU8.read(dataStream),
+ grosNombre: FfiConverterU64.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterTypeEnumeration.write(dataStream, value.un);
+ FfiConverterBool.write(dataStream, value.deux);
+ FfiConverterU8.write(dataStream, value.petitNombre);
+ FfiConverterU64.write(dataStream, value.grosNombre);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterTypeEnumeration.computeSize(value.un);
+ totalSize += FfiConverterBool.computeSize(value.deux);
+ totalSize += FfiConverterU8.computeSize(value.petitNombre);
+ totalSize += FfiConverterU64.computeSize(value.grosNombre);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof Dictionnaire)) {
+ throw new TypeError(`Expected 'Dictionnaire', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterTypeEnumeration.checkType(value.un);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".un");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterBool.checkType(value.deux);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".deux");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU8.checkType(value.petitNombre);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".petitNombre");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU64.checkType(value.grosNombre);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".grosNombre");
+ }
+ throw e;
+ }
+ }
+}
+
+export class DictionnaireNombres {
+ constructor({ petitNombre, courtNombre, nombreSimple, grosNombre } = {}) {
+ try {
+ FfiConverterU8.checkType(petitNombre)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("petitNombre");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU16.checkType(courtNombre)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("courtNombre");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU32.checkType(nombreSimple)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("nombreSimple");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU64.checkType(grosNombre)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("grosNombre");
+ }
+ throw e;
+ }
+ this.petitNombre = petitNombre;
+ this.courtNombre = courtNombre;
+ this.nombreSimple = nombreSimple;
+ this.grosNombre = grosNombre;
+ }
+ equals(other) {
+ return (
+ this.petitNombre == other.petitNombre &&
+ this.courtNombre == other.courtNombre &&
+ this.nombreSimple == other.nombreSimple &&
+ this.grosNombre == other.grosNombre
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeDictionnaireNombres extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new DictionnaireNombres({
+ petitNombre: FfiConverterU8.read(dataStream),
+ courtNombre: FfiConverterU16.read(dataStream),
+ nombreSimple: FfiConverterU32.read(dataStream),
+ grosNombre: FfiConverterU64.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterU8.write(dataStream, value.petitNombre);
+ FfiConverterU16.write(dataStream, value.courtNombre);
+ FfiConverterU32.write(dataStream, value.nombreSimple);
+ FfiConverterU64.write(dataStream, value.grosNombre);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterU8.computeSize(value.petitNombre);
+ totalSize += FfiConverterU16.computeSize(value.courtNombre);
+ totalSize += FfiConverterU32.computeSize(value.nombreSimple);
+ totalSize += FfiConverterU64.computeSize(value.grosNombre);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof DictionnaireNombres)) {
+ throw new TypeError(`Expected 'DictionnaireNombres', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterU8.checkType(value.petitNombre);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".petitNombre");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU16.checkType(value.courtNombre);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".courtNombre");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU32.checkType(value.nombreSimple);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".nombreSimple");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU64.checkType(value.grosNombre);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".grosNombre");
+ }
+ throw e;
+ }
+ }
+}
+
+export class DictionnaireNombresSignes {
+ constructor({ petitNombre, courtNombre, nombreSimple, grosNombre } = {}) {
+ try {
+ FfiConverterI8.checkType(petitNombre)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("petitNombre");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterI16.checkType(courtNombre)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("courtNombre");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterI32.checkType(nombreSimple)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("nombreSimple");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterI64.checkType(grosNombre)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("grosNombre");
+ }
+ throw e;
+ }
+ this.petitNombre = petitNombre;
+ this.courtNombre = courtNombre;
+ this.nombreSimple = nombreSimple;
+ this.grosNombre = grosNombre;
+ }
+ equals(other) {
+ return (
+ this.petitNombre == other.petitNombre &&
+ this.courtNombre == other.courtNombre &&
+ this.nombreSimple == other.nombreSimple &&
+ this.grosNombre == other.grosNombre
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeDictionnaireNombresSignes extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new DictionnaireNombresSignes({
+ petitNombre: FfiConverterI8.read(dataStream),
+ courtNombre: FfiConverterI16.read(dataStream),
+ nombreSimple: FfiConverterI32.read(dataStream),
+ grosNombre: FfiConverterI64.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterI8.write(dataStream, value.petitNombre);
+ FfiConverterI16.write(dataStream, value.courtNombre);
+ FfiConverterI32.write(dataStream, value.nombreSimple);
+ FfiConverterI64.write(dataStream, value.grosNombre);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterI8.computeSize(value.petitNombre);
+ totalSize += FfiConverterI16.computeSize(value.courtNombre);
+ totalSize += FfiConverterI32.computeSize(value.nombreSimple);
+ totalSize += FfiConverterI64.computeSize(value.grosNombre);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof DictionnaireNombresSignes)) {
+ throw new TypeError(`Expected 'DictionnaireNombresSignes', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterI8.checkType(value.petitNombre);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".petitNombre");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterI16.checkType(value.courtNombre);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".courtNombre");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterI32.checkType(value.nombreSimple);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".nombreSimple");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterI64.checkType(value.grosNombre);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".grosNombre");
+ }
+ throw e;
+ }
+ }
+}
+
+export class OptionneurDictionnaire {
+ constructor({ i8Var = -8, u8Var = 8, i16Var = -16, u16Var = 0x10, i32Var = -32, u32Var = 32, i64Var = -64, u64Var = 64, floatVar = 4.0, doubleVar = 8.0, booleanVar = true, stringVar = "default", listVar = [], enumerationVar = Enumeration.DEUX, dictionnaireVar = null } = {}) {
+ try {
+ FfiConverterI8.checkType(i8Var)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("i8Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU8.checkType(u8Var)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("u8Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterI16.checkType(i16Var)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("i16Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU16.checkType(u16Var)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("u16Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterI32.checkType(i32Var)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("i32Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU32.checkType(u32Var)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("u32Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterI64.checkType(i64Var)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("i64Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU64.checkType(u64Var)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("u64Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterF32.checkType(floatVar)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("floatVar");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterF64.checkType(doubleVar)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("doubleVar");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterBool.checkType(booleanVar)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("booleanVar");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(stringVar)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("stringVar");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterSequencestring.checkType(listVar)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("listVar");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterTypeEnumeration.checkType(enumerationVar)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("enumerationVar");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterOptionalTypeminusculeMajusculeEnum.checkType(dictionnaireVar)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("dictionnaireVar");
+ }
+ throw e;
+ }
+ this.i8Var = i8Var;
+ this.u8Var = u8Var;
+ this.i16Var = i16Var;
+ this.u16Var = u16Var;
+ this.i32Var = i32Var;
+ this.u32Var = u32Var;
+ this.i64Var = i64Var;
+ this.u64Var = u64Var;
+ this.floatVar = floatVar;
+ this.doubleVar = doubleVar;
+ this.booleanVar = booleanVar;
+ this.stringVar = stringVar;
+ this.listVar = listVar;
+ this.enumerationVar = enumerationVar;
+ this.dictionnaireVar = dictionnaireVar;
+ }
+ equals(other) {
+ return (
+ this.i8Var == other.i8Var &&
+ this.u8Var == other.u8Var &&
+ this.i16Var == other.i16Var &&
+ this.u16Var == other.u16Var &&
+ this.i32Var == other.i32Var &&
+ this.u32Var == other.u32Var &&
+ this.i64Var == other.i64Var &&
+ this.u64Var == other.u64Var &&
+ this.floatVar == other.floatVar &&
+ this.doubleVar == other.doubleVar &&
+ this.booleanVar == other.booleanVar &&
+ this.stringVar == other.stringVar &&
+ this.listVar == other.listVar &&
+ this.enumerationVar == other.enumerationVar &&
+ this.dictionnaireVar == other.dictionnaireVar
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeOptionneurDictionnaire extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new OptionneurDictionnaire({
+ i8Var: FfiConverterI8.read(dataStream),
+ u8Var: FfiConverterU8.read(dataStream),
+ i16Var: FfiConverterI16.read(dataStream),
+ u16Var: FfiConverterU16.read(dataStream),
+ i32Var: FfiConverterI32.read(dataStream),
+ u32Var: FfiConverterU32.read(dataStream),
+ i64Var: FfiConverterI64.read(dataStream),
+ u64Var: FfiConverterU64.read(dataStream),
+ floatVar: FfiConverterF32.read(dataStream),
+ doubleVar: FfiConverterF64.read(dataStream),
+ booleanVar: FfiConverterBool.read(dataStream),
+ stringVar: FfiConverterString.read(dataStream),
+ listVar: FfiConverterSequencestring.read(dataStream),
+ enumerationVar: FfiConverterTypeEnumeration.read(dataStream),
+ dictionnaireVar: FfiConverterOptionalTypeminusculeMajusculeEnum.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterI8.write(dataStream, value.i8Var);
+ FfiConverterU8.write(dataStream, value.u8Var);
+ FfiConverterI16.write(dataStream, value.i16Var);
+ FfiConverterU16.write(dataStream, value.u16Var);
+ FfiConverterI32.write(dataStream, value.i32Var);
+ FfiConverterU32.write(dataStream, value.u32Var);
+ FfiConverterI64.write(dataStream, value.i64Var);
+ FfiConverterU64.write(dataStream, value.u64Var);
+ FfiConverterF32.write(dataStream, value.floatVar);
+ FfiConverterF64.write(dataStream, value.doubleVar);
+ FfiConverterBool.write(dataStream, value.booleanVar);
+ FfiConverterString.write(dataStream, value.stringVar);
+ FfiConverterSequencestring.write(dataStream, value.listVar);
+ FfiConverterTypeEnumeration.write(dataStream, value.enumerationVar);
+ FfiConverterOptionalTypeminusculeMajusculeEnum.write(dataStream, value.dictionnaireVar);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterI8.computeSize(value.i8Var);
+ totalSize += FfiConverterU8.computeSize(value.u8Var);
+ totalSize += FfiConverterI16.computeSize(value.i16Var);
+ totalSize += FfiConverterU16.computeSize(value.u16Var);
+ totalSize += FfiConverterI32.computeSize(value.i32Var);
+ totalSize += FfiConverterU32.computeSize(value.u32Var);
+ totalSize += FfiConverterI64.computeSize(value.i64Var);
+ totalSize += FfiConverterU64.computeSize(value.u64Var);
+ totalSize += FfiConverterF32.computeSize(value.floatVar);
+ totalSize += FfiConverterF64.computeSize(value.doubleVar);
+ totalSize += FfiConverterBool.computeSize(value.booleanVar);
+ totalSize += FfiConverterString.computeSize(value.stringVar);
+ totalSize += FfiConverterSequencestring.computeSize(value.listVar);
+ totalSize += FfiConverterTypeEnumeration.computeSize(value.enumerationVar);
+ totalSize += FfiConverterOptionalTypeminusculeMajusculeEnum.computeSize(value.dictionnaireVar);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof OptionneurDictionnaire)) {
+ throw new TypeError(`Expected 'OptionneurDictionnaire', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterI8.checkType(value.i8Var);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".i8Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU8.checkType(value.u8Var);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".u8Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterI16.checkType(value.i16Var);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".i16Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU16.checkType(value.u16Var);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".u16Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterI32.checkType(value.i32Var);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".i32Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU32.checkType(value.u32Var);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".u32Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterI64.checkType(value.i64Var);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".i64Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterU64.checkType(value.u64Var);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".u64Var");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterF32.checkType(value.floatVar);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".floatVar");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterF64.checkType(value.doubleVar);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".doubleVar");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterBool.checkType(value.booleanVar);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".booleanVar");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterString.checkType(value.stringVar);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".stringVar");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterSequencestring.checkType(value.listVar);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".listVar");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterTypeEnumeration.checkType(value.enumerationVar);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".enumerationVar");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterOptionalTypeminusculeMajusculeEnum.checkType(value.dictionnaireVar);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".dictionnaireVar");
+ }
+ throw e;
+ }
+ }
+}
+
+export class MinusculeMajusculeDict {
+ constructor({ minusculeMajusculeField } = {}) {
+ try {
+ FfiConverterBool.checkType(minusculeMajusculeField)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("minusculeMajusculeField");
+ }
+ throw e;
+ }
+ this.minusculeMajusculeField = minusculeMajusculeField;
+ }
+ equals(other) {
+ return (
+ this.minusculeMajusculeField == other.minusculeMajusculeField
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeminusculeMajusculeDict extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new MinusculeMajusculeDict({
+ minusculeMajusculeField: FfiConverterBool.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterBool.write(dataStream, value.minusculeMajusculeField);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterBool.computeSize(value.minusculeMajusculeField);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof MinusculeMajusculeDict)) {
+ throw new TypeError(`Expected 'MinusculeMajusculeDict', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterBool.checkType(value.minusculeMajusculeField);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".minusculeMajusculeField");
+ }
+ throw e;
+ }
+ }
+}
+
+
+export const Enumeration = {
+ UN: 1,
+ DEUX: 2,
+ TROIS: 3,
+};
+
+Object.freeze(Enumeration);
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeEnumeration extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ switch (dataStream.readInt32()) {
+ case 1:
+ return Enumeration.UN
+ case 2:
+ return Enumeration.DEUX
+ case 3:
+ return Enumeration.TROIS
+ default:
+ return new Error("Unknown Enumeration variant");
+ }
+ }
+
+ static write(dataStream, value) {
+ if (value === Enumeration.UN) {
+ dataStream.writeInt32(1);
+ return;
+ }
+ if (value === Enumeration.DEUX) {
+ dataStream.writeInt32(2);
+ return;
+ }
+ if (value === Enumeration.TROIS) {
+ dataStream.writeInt32(3);
+ return;
+ }
+ return new Error("Unknown Enumeration variant");
+ }
+
+ static computeSize(value) {
+ return 4;
+ }
+
+ static checkType(value) {
+ if (!Number.isInteger(value) || value < 1 || value > 3) {
+ throw new UniFFITypeError(`${value} is not a valid value for Enumeration`);
+ }
+ }
+}
+
+
+
+export class EnumerationAvecDonnees {}
+EnumerationAvecDonnees.Zero = class extends EnumerationAvecDonnees{
+ constructor(
+ ) {
+ super();
+ }
+}
+EnumerationAvecDonnees.Un = class extends EnumerationAvecDonnees{
+ constructor(
+ premier
+ ) {
+ super();
+ this.premier = premier;
+ }
+}
+EnumerationAvecDonnees.Deux = class extends EnumerationAvecDonnees{
+ constructor(
+ premier,
+ second
+ ) {
+ super();
+ this.premier = premier;
+ this.second = second;
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeEnumerationAvecDonnees extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ switch (dataStream.readInt32()) {
+ case 1:
+ return new EnumerationAvecDonnees.Zero(
+ );
+ case 2:
+ return new EnumerationAvecDonnees.Un(
+ FfiConverterU32.read(dataStream)
+ );
+ case 3:
+ return new EnumerationAvecDonnees.Deux(
+ FfiConverterU32.read(dataStream),
+ FfiConverterString.read(dataStream)
+ );
+ default:
+ return new Error("Unknown EnumerationAvecDonnees variant");
+ }
+ }
+
+ static write(dataStream, value) {
+ if (value instanceof EnumerationAvecDonnees.Zero) {
+ dataStream.writeInt32(1);
+ return;
+ }
+ if (value instanceof EnumerationAvecDonnees.Un) {
+ dataStream.writeInt32(2);
+ FfiConverterU32.write(dataStream, value.premier);
+ return;
+ }
+ if (value instanceof EnumerationAvecDonnees.Deux) {
+ dataStream.writeInt32(3);
+ FfiConverterU32.write(dataStream, value.premier);
+ FfiConverterString.write(dataStream, value.second);
+ return;
+ }
+ return new Error("Unknown EnumerationAvecDonnees variant");
+ }
+
+ static computeSize(value) {
+ // Size of the Int indicating the variant
+ let totalSize = 4;
+ if (value instanceof EnumerationAvecDonnees.Zero) {
+ return totalSize;
+ }
+ if (value instanceof EnumerationAvecDonnees.Un) {
+ totalSize += FfiConverterU32.computeSize(value.premier);
+ return totalSize;
+ }
+ if (value instanceof EnumerationAvecDonnees.Deux) {
+ totalSize += FfiConverterU32.computeSize(value.premier);
+ totalSize += FfiConverterString.computeSize(value.second);
+ return totalSize;
+ }
+ return new Error("Unknown EnumerationAvecDonnees variant");
+ }
+
+ static checkType(value) {
+ if (!(value instanceof EnumerationAvecDonnees)) {
+ throw new UniFFITypeError(`${value} is not a subclass instance of EnumerationAvecDonnees`);
+ }
+ }
+}
+
+
+
+export const MinusculeMajusculeEnum = {
+ MINUSCULE_MAJUSCULE_VARIANT: 1,
+};
+
+Object.freeze(MinusculeMajusculeEnum);
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeminusculeMajusculeEnum extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ switch (dataStream.readInt32()) {
+ case 1:
+ return MinusculeMajusculeEnum.MINUSCULE_MAJUSCULE_VARIANT
+ default:
+ return new Error("Unknown MinusculeMajusculeEnum variant");
+ }
+ }
+
+ static write(dataStream, value) {
+ if (value === MinusculeMajusculeEnum.MINUSCULE_MAJUSCULE_VARIANT) {
+ dataStream.writeInt32(1);
+ return;
+ }
+ return new Error("Unknown MinusculeMajusculeEnum variant");
+ }
+
+ static computeSize(value) {
+ return 4;
+ }
+
+ static checkType(value) {
+ if (!Number.isInteger(value) || value < 1 || value > 1) {
+ throw new UniFFITypeError(`${value} is not a valid value for MinusculeMajusculeEnum`);
+ }
+ }
+}
+
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterOptionali32 extends FfiConverterArrayBuffer {
+ static checkType(value) {
+ if (value !== undefined && value !== null) {
+ FfiConverterI32.checkType(value)
+ }
+ }
+
+ static read(dataStream) {
+ const code = dataStream.readUint8(0);
+ switch (code) {
+ case 0:
+ return null
+ case 1:
+ return FfiConverterI32.read(dataStream)
+ default:
+ throw UniFFIError(`Unexpected code: ${code}`);
+ }
+ }
+
+ static write(dataStream, value) {
+ if (value === null || value === undefined) {
+ dataStream.writeUint8(0);
+ return;
+ }
+ dataStream.writeUint8(1);
+ FfiConverterI32.write(dataStream, value)
+ }
+
+ static computeSize(value) {
+ if (value === null || value === undefined) {
+ return 1;
+ }
+ return 1 + FfiConverterI32.computeSize(value)
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterOptionalstring extends FfiConverterArrayBuffer {
+ static checkType(value) {
+ if (value !== undefined && value !== null) {
+ FfiConverterString.checkType(value)
+ }
+ }
+
+ static read(dataStream) {
+ const code = dataStream.readUint8(0);
+ switch (code) {
+ case 0:
+ return null
+ case 1:
+ return FfiConverterString.read(dataStream)
+ default:
+ throw UniFFIError(`Unexpected code: ${code}`);
+ }
+ }
+
+ static write(dataStream, value) {
+ if (value === null || value === undefined) {
+ dataStream.writeUint8(0);
+ return;
+ }
+ dataStream.writeUint8(1);
+ FfiConverterString.write(dataStream, value)
+ }
+
+ static computeSize(value) {
+ if (value === null || value === undefined) {
+ return 1;
+ }
+ return 1 + FfiConverterString.computeSize(value)
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterOptionalTypeminusculeMajusculeEnum extends FfiConverterArrayBuffer {
+ static checkType(value) {
+ if (value !== undefined && value !== null) {
+ FfiConverterTypeminusculeMajusculeEnum.checkType(value)
+ }
+ }
+
+ static read(dataStream) {
+ const code = dataStream.readUint8(0);
+ switch (code) {
+ case 0:
+ return null
+ case 1:
+ return FfiConverterTypeminusculeMajusculeEnum.read(dataStream)
+ default:
+ throw UniFFIError(`Unexpected code: ${code}`);
+ }
+ }
+
+ static write(dataStream, value) {
+ if (value === null || value === undefined) {
+ dataStream.writeUint8(0);
+ return;
+ }
+ dataStream.writeUint8(1);
+ FfiConverterTypeminusculeMajusculeEnum.write(dataStream, value)
+ }
+
+ static computeSize(value) {
+ if (value === null || value === undefined) {
+ return 1;
+ }
+ return 1 + FfiConverterTypeminusculeMajusculeEnum.computeSize(value)
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterSequencestring extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ const len = dataStream.readInt32();
+ const arr = [];
+ for (let i = 0; i < len; i++) {
+ arr.push(FfiConverterString.read(dataStream));
+ }
+ return arr;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeInt32(value.length);
+ value.forEach((innerValue) => {
+ FfiConverterString.write(dataStream, innerValue);
+ })
+ }
+
+ static computeSize(value) {
+ // The size of the length
+ let size = 4;
+ for (const innerValue of value) {
+ size += FfiConverterString.computeSize(innerValue);
+ }
+ return size;
+ }
+
+ static checkType(value) {
+ if (!Array.isArray(value)) {
+ throw new UniFFITypeError(`${value} is not an array`);
+ }
+ value.forEach((innerValue, idx) => {
+ try {
+ FfiConverterString.checkType(innerValue);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(`[${idx}]`);
+ }
+ throw e;
+ }
+ })
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterSequenceTypeEnumeration extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ const len = dataStream.readInt32();
+ const arr = [];
+ for (let i = 0; i < len; i++) {
+ arr.push(FfiConverterTypeEnumeration.read(dataStream));
+ }
+ return arr;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeInt32(value.length);
+ value.forEach((innerValue) => {
+ FfiConverterTypeEnumeration.write(dataStream, innerValue);
+ })
+ }
+
+ static computeSize(value) {
+ // The size of the length
+ let size = 4;
+ for (const innerValue of value) {
+ size += FfiConverterTypeEnumeration.computeSize(innerValue);
+ }
+ return size;
+ }
+
+ static checkType(value) {
+ if (!Array.isArray(value)) {
+ throw new UniFFITypeError(`${value} is not an array`);
+ }
+ value.forEach((innerValue, idx) => {
+ try {
+ FfiConverterTypeEnumeration.checkType(innerValue);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(`[${idx}]`);
+ }
+ throw e;
+ }
+ })
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterMapStringTypeEnumerationAvecDonnees extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ const len = dataStream.readInt32();
+ const map = {};
+ for (let i = 0; i < len; i++) {
+ const key = FfiConverterString.read(dataStream);
+ const value = FfiConverterTypeEnumerationAvecDonnees.read(dataStream);
+ map[key] = value;
+ }
+
+ return map;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeInt32(Object.keys(value).length);
+ for (const key in value) {
+ FfiConverterString.write(dataStream, key);
+ FfiConverterTypeEnumerationAvecDonnees.write(dataStream, value[key]);
+ }
+ }
+
+ static computeSize(value) {
+ // The size of the length
+ let size = 4;
+ for (const key in value) {
+ size += FfiConverterString.computeSize(key);
+ size += FfiConverterTypeEnumerationAvecDonnees.computeSize(value[key]);
+ }
+ return size;
+ }
+
+ static checkType(value) {
+ for (const key in value) {
+ try {
+ FfiConverterString.checkType(key);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("(key)");
+ }
+ throw e;
+ }
+
+ try {
+ FfiConverterTypeEnumerationAvecDonnees.checkType(value[key]);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(`[${key}]`);
+ }
+ throw e;
+ }
+ }
+ }
+}
+
+
+
+
+
+export function copieCarte(c) {
+
+ const liftResult = (result) => FfiConverterMapStringTypeEnumerationAvecDonnees.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterMapStringTypeEnumerationAvecDonnees.checkType(c)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("c");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 101, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_carte
+ FfiConverterMapStringTypeEnumerationAvecDonnees.lower(c),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
+
+export function copieDictionnaire(d) {
+
+ const liftResult = (result) => FfiConverterTypeDictionnaire.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypeDictionnaire.checkType(d)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("d");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 102, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_dictionnaire
+ FfiConverterTypeDictionnaire.lower(d),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
+
+export function copieEnumeration(e) {
+
+ const liftResult = (result) => FfiConverterTypeEnumeration.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypeEnumeration.checkType(e)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("e");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 103, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_enumeration
+ FfiConverterTypeEnumeration.lower(e),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
+
+export function copieEnumerations(e) {
+
+ const liftResult = (result) => FfiConverterSequenceTypeEnumeration.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterSequenceTypeEnumeration.checkType(e)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("e");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 104, // rondpoint:uniffi_uniffi_rondpoint_fn_func_copie_enumerations
+ FfiConverterSequenceTypeEnumeration.lower(e),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
+
+export function switcheroo(b) {
+
+ const liftResult = (result) => FfiConverterBool.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterBool.checkType(b)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("b");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 105, // rondpoint:uniffi_uniffi_rondpoint_fn_func_switcheroo
+ FfiConverterBool.lower(b),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustSprites.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustSprites.sys.mjs
new file mode 100644
index 0000000000..b404af06b1
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustSprites.sys.mjs
@@ -0,0 +1,687 @@
+// This file was autogenerated by the `uniffi-bindgen-gecko-js` crate.
+// Trust me, you don't want to mess with it!
+
+import { UniFFITypeError } from "resource://gre/modules/UniFFI.sys.mjs";
+
+
+
+// Objects intended to be used in the unit tests
+export var UnitTestObjs = {};
+
+// Write/Read data to/from an ArrayBuffer
+class ArrayBufferDataStream {
+ constructor(arrayBuffer) {
+ this.dataView = new DataView(arrayBuffer);
+ this.pos = 0;
+ }
+
+ readUint8() {
+ let rv = this.dataView.getUint8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeUint8(value) {
+ this.dataView.setUint8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readUint16() {
+ let rv = this.dataView.getUint16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeUint16(value) {
+ this.dataView.setUint16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readUint32() {
+ let rv = this.dataView.getUint32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeUint32(value) {
+ this.dataView.setUint32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readUint64() {
+ let rv = this.dataView.getBigUint64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeUint64(value) {
+ this.dataView.setBigUint64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+
+ readInt8() {
+ let rv = this.dataView.getInt8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeInt8(value) {
+ this.dataView.setInt8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readInt16() {
+ let rv = this.dataView.getInt16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeInt16(value) {
+ this.dataView.setInt16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readInt32() {
+ let rv = this.dataView.getInt32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeInt32(value) {
+ this.dataView.setInt32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readInt64() {
+ let rv = this.dataView.getBigInt64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeInt64(value) {
+ this.dataView.setBigInt64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+ readFloat32() {
+ let rv = this.dataView.getFloat32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeFloat32(value) {
+ this.dataView.setFloat32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readFloat64() {
+ let rv = this.dataView.getFloat64(this.pos);
+ this.pos += 8;
+ return rv;
+ }
+
+ writeFloat64(value) {
+ this.dataView.setFloat64(this.pos, value);
+ this.pos += 8;
+ }
+
+
+ writeString(value) {
+ const encoder = new TextEncoder();
+ // Note: in order to efficiently write this data, we first write the
+ // string data, reserving 4 bytes for the size.
+ const dest = new Uint8Array(this.dataView.buffer, this.pos + 4);
+ const encodeResult = encoder.encodeInto(value, dest);
+ if (encodeResult.read != value.length) {
+ throw new UniFFIError(
+ "writeString: out of space when writing to ArrayBuffer. Did the computeSize() method returned the wrong result?"
+ );
+ }
+ const size = encodeResult.written;
+ // Next, go back and write the size before the string data
+ this.dataView.setUint32(this.pos, size);
+ // Finally, advance our position past both the size and string data
+ this.pos += size + 4;
+ }
+
+ readString() {
+ const decoder = new TextDecoder();
+ const size = this.readUint32();
+ const source = new Uint8Array(this.dataView.buffer, this.pos, size)
+ const value = decoder.decode(source);
+ this.pos += size;
+ return value;
+ }
+
+ // Reads a Sprite pointer from the data stream
+ // UniFFI Pointers are **always** 8 bytes long. That is enforced
+ // by the C++ and Rust Scaffolding code.
+ readPointerSprite() {
+ const pointerId = 8; // sprites:Sprite
+ const res = UniFFIScaffolding.readPointer(pointerId, this.dataView.buffer, this.pos);
+ this.pos += 8;
+ return res;
+ }
+
+ // Writes a Sprite pointer into the data stream
+ // UniFFI Pointers are **always** 8 bytes long. That is enforced
+ // by the C++ and Rust Scaffolding code.
+ writePointerSprite(value) {
+ const pointerId = 8; // sprites:Sprite
+ UniFFIScaffolding.writePointer(pointerId, value, this.dataView.buffer, this.pos);
+ this.pos += 8;
+ }
+
+}
+
+function handleRustResult(result, liftCallback, liftErrCallback) {
+ switch (result.code) {
+ case "success":
+ return liftCallback(result.data);
+
+ case "error":
+ throw liftErrCallback(result.data);
+
+ case "internal-error":
+ let message = result.internalErrorMessage;
+ if (message) {
+ throw new UniFFIInternalError(message);
+ } else {
+ throw new UniFFIInternalError("Unknown error");
+ }
+
+ default:
+ throw new UniFFIError(`Unexpected status code: ${result.code}`);
+ }
+}
+
+class UniFFIError {
+ constructor(message) {
+ this.message = message;
+ }
+
+ toString() {
+ return `UniFFIError: ${this.message}`
+ }
+}
+
+class UniFFIInternalError extends UniFFIError {}
+
+// Base class for FFI converters
+class FfiConverter {
+ // throw `UniFFITypeError` if a value to be converted has an invalid type
+ static checkType(value) {
+ if (value === undefined ) {
+ throw new UniFFITypeError(`undefined`);
+ }
+ if (value === null ) {
+ throw new UniFFITypeError(`null`);
+ }
+ }
+}
+
+// Base class for FFI converters that lift/lower by reading/writing to an ArrayBuffer
+class FfiConverterArrayBuffer extends FfiConverter {
+ static lift(buf) {
+ return this.read(new ArrayBufferDataStream(buf));
+ }
+
+ static lower(value) {
+ const buf = new ArrayBuffer(this.computeSize(value));
+ const dataStream = new ArrayBufferDataStream(buf);
+ this.write(dataStream, value);
+ return buf;
+ }
+}
+
+// Symbols that are used to ensure that Object constructors
+// can only be used with a proper UniFFI pointer
+const uniffiObjectPtr = Symbol("uniffiObjectPtr");
+const constructUniffiObject = Symbol("constructUniffiObject");
+UnitTestObjs.uniffiObjectPtr = uniffiObjectPtr;
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterF64 extends FfiConverter {
+ static computeSize() {
+ return 8;
+ }
+ static lift(value) {
+ return value;
+ }
+ static lower(value) {
+ return value;
+ }
+ static write(dataStream, value) {
+ dataStream.writeFloat64(value)
+ }
+ static read(dataStream) {
+ return dataStream.readFloat64()
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterString extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (typeof value !== "string") {
+ throw new UniFFITypeError(`${value} is not a string`);
+ }
+ }
+
+ static lift(buf) {
+ const decoder = new TextDecoder();
+ const utf8Arr = new Uint8Array(buf);
+ return decoder.decode(utf8Arr);
+ }
+ static lower(value) {
+ const encoder = new TextEncoder();
+ return encoder.encode(value).buffer;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeString(value);
+ }
+
+ static read(dataStream) {
+ return dataStream.readString();
+ }
+
+ static computeSize(value) {
+ const encoder = new TextEncoder();
+ return 4 + encoder.encode(value).length
+ }
+}
+
+export class Sprite {
+ // Use `init` to instantiate this class.
+ // DO NOT USE THIS CONSTRUCTOR DIRECTLY
+ constructor(opts) {
+ if (!Object.prototype.hasOwnProperty.call(opts, constructUniffiObject)) {
+ throw new UniFFIError("Attempting to construct an object using the JavaScript constructor directly" +
+ "Please use a UDL defined constructor, or the init function for the primary constructor")
+ }
+ if (!opts[constructUniffiObject] instanceof UniFFIPointer) {
+ throw new UniFFIError("Attempting to create a UniFFI object with a pointer that is not an instance of UniFFIPointer")
+ }
+ this[uniffiObjectPtr] = opts[constructUniffiObject];
+ }
+ /**
+ * An async constructor for Sprite.
+ *
+ * @returns {Promise<Sprite>}: A promise that resolves
+ * to a newly constructed Sprite
+ */
+ static init(initialPosition) {
+ const liftResult = (result) => FfiConverterTypeSprite.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterOptionalTypePoint.checkType(initialPosition)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("initialPosition");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 106, // sprites:uniffi_uniffi_sprites_fn_constructor_sprite_new
+ FfiConverterOptionalTypePoint.lower(initialPosition),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }}
+ /**
+ * An async constructor for Sprite.
+ *
+ * @returns {Promise<Sprite>}: A promise that resolves
+ * to a newly constructed Sprite
+ */
+ static newRelativeTo(reference,direction) {
+ const liftResult = (result) => FfiConverterTypeSprite.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypePoint.checkType(reference)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("reference");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterTypeVector.checkType(direction)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("direction");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 107, // sprites:uniffi_uniffi_sprites_fn_constructor_sprite_new_relative_to
+ FfiConverterTypePoint.lower(reference),
+ FfiConverterTypeVector.lower(direction),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }}
+
+ getPosition() {
+ const liftResult = (result) => FfiConverterTypePoint.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ return UniFFIScaffolding.callAsync(
+ 108, // sprites:uniffi_uniffi_sprites_fn_method_sprite_get_position
+ FfiConverterTypeSprite.lower(this),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ moveBy(direction) {
+ const liftResult = (result) => undefined;
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypeVector.checkType(direction)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("direction");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 109, // sprites:uniffi_uniffi_sprites_fn_method_sprite_move_by
+ FfiConverterTypeSprite.lower(this),
+ FfiConverterTypeVector.lower(direction),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ moveTo(position) {
+ const liftResult = (result) => undefined;
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypePoint.checkType(position)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("position");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 110, // sprites:uniffi_uniffi_sprites_fn_method_sprite_move_to
+ FfiConverterTypeSprite.lower(this),
+ FfiConverterTypePoint.lower(position),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeSprite extends FfiConverter {
+ static lift(value) {
+ const opts = {};
+ opts[constructUniffiObject] = value;
+ return new Sprite(opts);
+ }
+
+ static lower(value) {
+ return value[uniffiObjectPtr];
+ }
+
+ static read(dataStream) {
+ return this.lift(dataStream.readPointerSprite());
+ }
+
+ static write(dataStream, value) {
+ dataStream.writePointerSprite(value[uniffiObjectPtr]);
+ }
+
+ static computeSize(value) {
+ return 8;
+ }
+}
+
+export class Point {
+ constructor({ x, y } = {}) {
+ try {
+ FfiConverterF64.checkType(x)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("x");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterF64.checkType(y)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("y");
+ }
+ throw e;
+ }
+ this.x = x;
+ this.y = y;
+ }
+ equals(other) {
+ return (
+ this.x == other.x &&
+ this.y == other.y
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypePoint extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new Point({
+ x: FfiConverterF64.read(dataStream),
+ y: FfiConverterF64.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterF64.write(dataStream, value.x);
+ FfiConverterF64.write(dataStream, value.y);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterF64.computeSize(value.x);
+ totalSize += FfiConverterF64.computeSize(value.y);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof Point)) {
+ throw new TypeError(`Expected 'Point', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterF64.checkType(value.x);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".x");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterF64.checkType(value.y);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".y");
+ }
+ throw e;
+ }
+ }
+}
+
+export class Vector {
+ constructor({ dx, dy } = {}) {
+ try {
+ FfiConverterF64.checkType(dx)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("dx");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterF64.checkType(dy)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("dy");
+ }
+ throw e;
+ }
+ this.dx = dx;
+ this.dy = dy;
+ }
+ equals(other) {
+ return (
+ this.dx == other.dx &&
+ this.dy == other.dy
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeVector extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new Vector({
+ dx: FfiConverterF64.read(dataStream),
+ dy: FfiConverterF64.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterF64.write(dataStream, value.dx);
+ FfiConverterF64.write(dataStream, value.dy);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterF64.computeSize(value.dx);
+ totalSize += FfiConverterF64.computeSize(value.dy);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof Vector)) {
+ throw new TypeError(`Expected 'Vector', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterF64.checkType(value.dx);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".dx");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterF64.checkType(value.dy);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".dy");
+ }
+ throw e;
+ }
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterOptionalTypePoint extends FfiConverterArrayBuffer {
+ static checkType(value) {
+ if (value !== undefined && value !== null) {
+ FfiConverterTypePoint.checkType(value)
+ }
+ }
+
+ static read(dataStream) {
+ const code = dataStream.readUint8(0);
+ switch (code) {
+ case 0:
+ return null
+ case 1:
+ return FfiConverterTypePoint.read(dataStream)
+ default:
+ throw UniFFIError(`Unexpected code: ${code}`);
+ }
+ }
+
+ static write(dataStream, value) {
+ if (value === null || value === undefined) {
+ dataStream.writeUint8(0);
+ return;
+ }
+ dataStream.writeUint8(1);
+ FfiConverterTypePoint.write(dataStream, value)
+ }
+
+ static computeSize(value) {
+ if (value === null || value === undefined) {
+ return 1;
+ }
+ return 1 + FfiConverterTypePoint.computeSize(value)
+ }
+}
+
+
+
+
+
+export function translate(position,direction) {
+
+ const liftResult = (result) => FfiConverterTypePoint.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypePoint.checkType(position)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("position");
+ }
+ throw e;
+ }
+ try {
+ FfiConverterTypeVector.checkType(direction)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("direction");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 111, // sprites:uniffi_uniffi_sprites_fn_func_translate
+ FfiConverterTypePoint.lower(position),
+ FfiConverterTypeVector.lower(direction),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustTodolist.sys.mjs b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustTodolist.sys.mjs
new file mode 100644
index 0000000000..59996b78fa
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/generated/RustTodolist.sys.mjs
@@ -0,0 +1,929 @@
+// This file was autogenerated by the `uniffi-bindgen-gecko-js` crate.
+// Trust me, you don't want to mess with it!
+
+import { UniFFITypeError } from "resource://gre/modules/UniFFI.sys.mjs";
+
+
+
+// Objects intended to be used in the unit tests
+export var UnitTestObjs = {};
+
+// Write/Read data to/from an ArrayBuffer
+class ArrayBufferDataStream {
+ constructor(arrayBuffer) {
+ this.dataView = new DataView(arrayBuffer);
+ this.pos = 0;
+ }
+
+ readUint8() {
+ let rv = this.dataView.getUint8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeUint8(value) {
+ this.dataView.setUint8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readUint16() {
+ let rv = this.dataView.getUint16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeUint16(value) {
+ this.dataView.setUint16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readUint32() {
+ let rv = this.dataView.getUint32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeUint32(value) {
+ this.dataView.setUint32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readUint64() {
+ let rv = this.dataView.getBigUint64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeUint64(value) {
+ this.dataView.setBigUint64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+
+ readInt8() {
+ let rv = this.dataView.getInt8(this.pos);
+ this.pos += 1;
+ return rv;
+ }
+
+ writeInt8(value) {
+ this.dataView.setInt8(this.pos, value);
+ this.pos += 1;
+ }
+
+ readInt16() {
+ let rv = this.dataView.getInt16(this.pos);
+ this.pos += 2;
+ return rv;
+ }
+
+ writeInt16(value) {
+ this.dataView.setInt16(this.pos, value);
+ this.pos += 2;
+ }
+
+ readInt32() {
+ let rv = this.dataView.getInt32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeInt32(value) {
+ this.dataView.setInt32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readInt64() {
+ let rv = this.dataView.getBigInt64(this.pos);
+ this.pos += 8;
+ return Number(rv);
+ }
+
+ writeInt64(value) {
+ this.dataView.setBigInt64(this.pos, BigInt(value));
+ this.pos += 8;
+ }
+
+ readFloat32() {
+ let rv = this.dataView.getFloat32(this.pos);
+ this.pos += 4;
+ return rv;
+ }
+
+ writeFloat32(value) {
+ this.dataView.setFloat32(this.pos, value);
+ this.pos += 4;
+ }
+
+ readFloat64() {
+ let rv = this.dataView.getFloat64(this.pos);
+ this.pos += 8;
+ return rv;
+ }
+
+ writeFloat64(value) {
+ this.dataView.setFloat64(this.pos, value);
+ this.pos += 8;
+ }
+
+
+ writeString(value) {
+ const encoder = new TextEncoder();
+ // Note: in order to efficiently write this data, we first write the
+ // string data, reserving 4 bytes for the size.
+ const dest = new Uint8Array(this.dataView.buffer, this.pos + 4);
+ const encodeResult = encoder.encodeInto(value, dest);
+ if (encodeResult.read != value.length) {
+ throw new UniFFIError(
+ "writeString: out of space when writing to ArrayBuffer. Did the computeSize() method returned the wrong result?"
+ );
+ }
+ const size = encodeResult.written;
+ // Next, go back and write the size before the string data
+ this.dataView.setUint32(this.pos, size);
+ // Finally, advance our position past both the size and string data
+ this.pos += size + 4;
+ }
+
+ readString() {
+ const decoder = new TextDecoder();
+ const size = this.readUint32();
+ const source = new Uint8Array(this.dataView.buffer, this.pos, size)
+ const value = decoder.decode(source);
+ this.pos += size;
+ return value;
+ }
+
+ // Reads a TodoList pointer from the data stream
+ // UniFFI Pointers are **always** 8 bytes long. That is enforced
+ // by the C++ and Rust Scaffolding code.
+ readPointerTodoList() {
+ const pointerId = 9; // todolist:TodoList
+ const res = UniFFIScaffolding.readPointer(pointerId, this.dataView.buffer, this.pos);
+ this.pos += 8;
+ return res;
+ }
+
+ // Writes a TodoList pointer into the data stream
+ // UniFFI Pointers are **always** 8 bytes long. That is enforced
+ // by the C++ and Rust Scaffolding code.
+ writePointerTodoList(value) {
+ const pointerId = 9; // todolist:TodoList
+ UniFFIScaffolding.writePointer(pointerId, value, this.dataView.buffer, this.pos);
+ this.pos += 8;
+ }
+
+}
+
+function handleRustResult(result, liftCallback, liftErrCallback) {
+ switch (result.code) {
+ case "success":
+ return liftCallback(result.data);
+
+ case "error":
+ throw liftErrCallback(result.data);
+
+ case "internal-error":
+ let message = result.internalErrorMessage;
+ if (message) {
+ throw new UniFFIInternalError(message);
+ } else {
+ throw new UniFFIInternalError("Unknown error");
+ }
+
+ default:
+ throw new UniFFIError(`Unexpected status code: ${result.code}`);
+ }
+}
+
+class UniFFIError {
+ constructor(message) {
+ this.message = message;
+ }
+
+ toString() {
+ return `UniFFIError: ${this.message}`
+ }
+}
+
+class UniFFIInternalError extends UniFFIError {}
+
+// Base class for FFI converters
+class FfiConverter {
+ // throw `UniFFITypeError` if a value to be converted has an invalid type
+ static checkType(value) {
+ if (value === undefined ) {
+ throw new UniFFITypeError(`undefined`);
+ }
+ if (value === null ) {
+ throw new UniFFITypeError(`null`);
+ }
+ }
+}
+
+// Base class for FFI converters that lift/lower by reading/writing to an ArrayBuffer
+class FfiConverterArrayBuffer extends FfiConverter {
+ static lift(buf) {
+ return this.read(new ArrayBufferDataStream(buf));
+ }
+
+ static lower(value) {
+ const buf = new ArrayBuffer(this.computeSize(value));
+ const dataStream = new ArrayBufferDataStream(buf);
+ this.write(dataStream, value);
+ return buf;
+ }
+}
+
+// Symbols that are used to ensure that Object constructors
+// can only be used with a proper UniFFI pointer
+const uniffiObjectPtr = Symbol("uniffiObjectPtr");
+const constructUniffiObject = Symbol("constructUniffiObject");
+UnitTestObjs.uniffiObjectPtr = uniffiObjectPtr;
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterString extends FfiConverter {
+ static checkType(value) {
+ super.checkType(value);
+ if (typeof value !== "string") {
+ throw new UniFFITypeError(`${value} is not a string`);
+ }
+ }
+
+ static lift(buf) {
+ const decoder = new TextDecoder();
+ const utf8Arr = new Uint8Array(buf);
+ return decoder.decode(utf8Arr);
+ }
+ static lower(value) {
+ const encoder = new TextEncoder();
+ return encoder.encode(value).buffer;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeString(value);
+ }
+
+ static read(dataStream) {
+ return dataStream.readString();
+ }
+
+ static computeSize(value) {
+ const encoder = new TextEncoder();
+ return 4 + encoder.encode(value).length
+ }
+}
+
+export class TodoList {
+ // Use `init` to instantiate this class.
+ // DO NOT USE THIS CONSTRUCTOR DIRECTLY
+ constructor(opts) {
+ if (!Object.prototype.hasOwnProperty.call(opts, constructUniffiObject)) {
+ throw new UniFFIError("Attempting to construct an object using the JavaScript constructor directly" +
+ "Please use a UDL defined constructor, or the init function for the primary constructor")
+ }
+ if (!opts[constructUniffiObject] instanceof UniFFIPointer) {
+ throw new UniFFIError("Attempting to create a UniFFI object with a pointer that is not an instance of UniFFIPointer")
+ }
+ this[uniffiObjectPtr] = opts[constructUniffiObject];
+ }
+ /**
+ * An async constructor for TodoList.
+ *
+ * @returns {Promise<TodoList>}: A promise that resolves
+ * to a newly constructed TodoList
+ */
+ static init() {
+ const liftResult = (result) => FfiConverterTypeTodoList.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ return UniFFIScaffolding.callAsync(
+ 112, // todolist:uniffi_uniffi_todolist_fn_constructor_todolist_new
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }}
+
+ addEntries(entries) {
+ const liftResult = (result) => undefined;
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterSequenceTypeTodoEntry.checkType(entries)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("entries");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 113, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_entries
+ FfiConverterTypeTodoList.lower(this),
+ FfiConverterSequenceTypeTodoEntry.lower(entries),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ addEntry(entry) {
+ const liftResult = (result) => undefined;
+ const liftError = (data) => FfiConverterTypeTodoError.lift(data);
+ const functionCall = () => {
+ try {
+ FfiConverterTypeTodoEntry.checkType(entry)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("entry");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 114, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_entry
+ FfiConverterTypeTodoList.lower(this),
+ FfiConverterTypeTodoEntry.lower(entry),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ addItem(todo) {
+ const liftResult = (result) => undefined;
+ const liftError = (data) => FfiConverterTypeTodoError.lift(data);
+ const functionCall = () => {
+ try {
+ FfiConverterString.checkType(todo)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("todo");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 115, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_item
+ FfiConverterTypeTodoList.lower(this),
+ FfiConverterString.lower(todo),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ addItems(items) {
+ const liftResult = (result) => undefined;
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterSequencestring.checkType(items)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("items");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 116, // todolist:uniffi_uniffi_todolist_fn_method_todolist_add_items
+ FfiConverterTypeTodoList.lower(this),
+ FfiConverterSequencestring.lower(items),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ clearItem(todo) {
+ const liftResult = (result) => undefined;
+ const liftError = (data) => FfiConverterTypeTodoError.lift(data);
+ const functionCall = () => {
+ try {
+ FfiConverterString.checkType(todo)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("todo");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 117, // todolist:uniffi_uniffi_todolist_fn_method_todolist_clear_item
+ FfiConverterTypeTodoList.lower(this),
+ FfiConverterString.lower(todo),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ getEntries() {
+ const liftResult = (result) => FfiConverterSequenceTypeTodoEntry.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ return UniFFIScaffolding.callAsync(
+ 118, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_entries
+ FfiConverterTypeTodoList.lower(this),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ getFirst() {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = (data) => FfiConverterTypeTodoError.lift(data);
+ const functionCall = () => {
+ return UniFFIScaffolding.callAsync(
+ 119, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_first
+ FfiConverterTypeTodoList.lower(this),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ getItems() {
+ const liftResult = (result) => FfiConverterSequencestring.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ return UniFFIScaffolding.callAsync(
+ 120, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_items
+ FfiConverterTypeTodoList.lower(this),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ getLast() {
+ const liftResult = (result) => FfiConverterString.lift(result);
+ const liftError = (data) => FfiConverterTypeTodoError.lift(data);
+ const functionCall = () => {
+ return UniFFIScaffolding.callAsync(
+ 121, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_last
+ FfiConverterTypeTodoList.lower(this),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ getLastEntry() {
+ const liftResult = (result) => FfiConverterTypeTodoEntry.lift(result);
+ const liftError = (data) => FfiConverterTypeTodoError.lift(data);
+ const functionCall = () => {
+ return UniFFIScaffolding.callAsync(
+ 122, // todolist:uniffi_uniffi_todolist_fn_method_todolist_get_last_entry
+ FfiConverterTypeTodoList.lower(this),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+ makeDefault() {
+ const liftResult = (result) => undefined;
+ const liftError = null;
+ const functionCall = () => {
+ return UniFFIScaffolding.callAsync(
+ 123, // todolist:uniffi_uniffi_todolist_fn_method_todolist_make_default
+ FfiConverterTypeTodoList.lower(this),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+ }
+
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeTodoList extends FfiConverter {
+ static lift(value) {
+ const opts = {};
+ opts[constructUniffiObject] = value;
+ return new TodoList(opts);
+ }
+
+ static lower(value) {
+ return value[uniffiObjectPtr];
+ }
+
+ static read(dataStream) {
+ return this.lift(dataStream.readPointerTodoList());
+ }
+
+ static write(dataStream, value) {
+ dataStream.writePointerTodoList(value[uniffiObjectPtr]);
+ }
+
+ static computeSize(value) {
+ return 8;
+ }
+}
+
+export class TodoEntry {
+ constructor({ text } = {}) {
+ try {
+ FfiConverterString.checkType(text)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("text");
+ }
+ throw e;
+ }
+ this.text = text;
+ }
+ equals(other) {
+ return (
+ this.text == other.text
+ )
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeTodoEntry extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ return new TodoEntry({
+ text: FfiConverterString.read(dataStream),
+ });
+ }
+ static write(dataStream, value) {
+ FfiConverterString.write(dataStream, value.text);
+ }
+
+ static computeSize(value) {
+ let totalSize = 0;
+ totalSize += FfiConverterString.computeSize(value.text);
+ return totalSize
+ }
+
+ static checkType(value) {
+ super.checkType(value);
+ if (!(value instanceof TodoEntry)) {
+ throw new TypeError(`Expected 'TodoEntry', found '${typeof value}'`);
+ }
+ try {
+ FfiConverterString.checkType(value.text);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(".text");
+ }
+ throw e;
+ }
+ }
+}
+
+
+
+
+export class TodoError extends Error {}
+
+
+export class TodoDoesNotExist extends TodoError {
+
+ constructor(message, ...params) {
+ super(...params);
+ this.message = message;
+ }
+ toString() {
+ return `TodoDoesNotExist: ${super.toString()}`
+ }
+}
+
+export class EmptyTodoList extends TodoError {
+
+ constructor(message, ...params) {
+ super(...params);
+ this.message = message;
+ }
+ toString() {
+ return `EmptyTodoList: ${super.toString()}`
+ }
+}
+
+export class DuplicateTodo extends TodoError {
+
+ constructor(message, ...params) {
+ super(...params);
+ this.message = message;
+ }
+ toString() {
+ return `DuplicateTodo: ${super.toString()}`
+ }
+}
+
+export class EmptyString extends TodoError {
+
+ constructor(message, ...params) {
+ super(...params);
+ this.message = message;
+ }
+ toString() {
+ return `EmptyString: ${super.toString()}`
+ }
+}
+
+export class DeligatedError extends TodoError {
+
+ constructor(message, ...params) {
+ super(...params);
+ this.message = message;
+ }
+ toString() {
+ return `DeligatedError: ${super.toString()}`
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterTypeTodoError extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ switch (dataStream.readInt32()) {
+ case 1:
+ return new TodoDoesNotExist(FfiConverterString.read(dataStream));
+ case 2:
+ return new EmptyTodoList(FfiConverterString.read(dataStream));
+ case 3:
+ return new DuplicateTodo(FfiConverterString.read(dataStream));
+ case 4:
+ return new EmptyString(FfiConverterString.read(dataStream));
+ case 5:
+ return new DeligatedError(FfiConverterString.read(dataStream));
+ default:
+ throw new Error("Unknown TodoError variant");
+ }
+ }
+ static computeSize(value) {
+ // Size of the Int indicating the variant
+ let totalSize = 4;
+ if (value instanceof TodoDoesNotExist) {
+ return totalSize;
+ }
+ if (value instanceof EmptyTodoList) {
+ return totalSize;
+ }
+ if (value instanceof DuplicateTodo) {
+ return totalSize;
+ }
+ if (value instanceof EmptyString) {
+ return totalSize;
+ }
+ if (value instanceof DeligatedError) {
+ return totalSize;
+ }
+ throw new Error("Unknown TodoError variant");
+ }
+ static write(dataStream, value) {
+ if (value instanceof TodoDoesNotExist) {
+ dataStream.writeInt32(1);
+ return;
+ }
+ if (value instanceof EmptyTodoList) {
+ dataStream.writeInt32(2);
+ return;
+ }
+ if (value instanceof DuplicateTodo) {
+ dataStream.writeInt32(3);
+ return;
+ }
+ if (value instanceof EmptyString) {
+ dataStream.writeInt32(4);
+ return;
+ }
+ if (value instanceof DeligatedError) {
+ dataStream.writeInt32(5);
+ return;
+ }
+ throw new Error("Unknown TodoError variant");
+ }
+
+ static errorClass = TodoError;
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterOptionalTypeTodoList extends FfiConverterArrayBuffer {
+ static checkType(value) {
+ if (value !== undefined && value !== null) {
+ FfiConverterTypeTodoList.checkType(value)
+ }
+ }
+
+ static read(dataStream) {
+ const code = dataStream.readUint8(0);
+ switch (code) {
+ case 0:
+ return null
+ case 1:
+ return FfiConverterTypeTodoList.read(dataStream)
+ default:
+ throw UniFFIError(`Unexpected code: ${code}`);
+ }
+ }
+
+ static write(dataStream, value) {
+ if (value === null || value === undefined) {
+ dataStream.writeUint8(0);
+ return;
+ }
+ dataStream.writeUint8(1);
+ FfiConverterTypeTodoList.write(dataStream, value)
+ }
+
+ static computeSize(value) {
+ if (value === null || value === undefined) {
+ return 1;
+ }
+ return 1 + FfiConverterTypeTodoList.computeSize(value)
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterSequencestring extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ const len = dataStream.readInt32();
+ const arr = [];
+ for (let i = 0; i < len; i++) {
+ arr.push(FfiConverterString.read(dataStream));
+ }
+ return arr;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeInt32(value.length);
+ value.forEach((innerValue) => {
+ FfiConverterString.write(dataStream, innerValue);
+ })
+ }
+
+ static computeSize(value) {
+ // The size of the length
+ let size = 4;
+ for (const innerValue of value) {
+ size += FfiConverterString.computeSize(innerValue);
+ }
+ return size;
+ }
+
+ static checkType(value) {
+ if (!Array.isArray(value)) {
+ throw new UniFFITypeError(`${value} is not an array`);
+ }
+ value.forEach((innerValue, idx) => {
+ try {
+ FfiConverterString.checkType(innerValue);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(`[${idx}]`);
+ }
+ throw e;
+ }
+ })
+ }
+}
+
+// Export the FFIConverter object to make external types work.
+export class FfiConverterSequenceTypeTodoEntry extends FfiConverterArrayBuffer {
+ static read(dataStream) {
+ const len = dataStream.readInt32();
+ const arr = [];
+ for (let i = 0; i < len; i++) {
+ arr.push(FfiConverterTypeTodoEntry.read(dataStream));
+ }
+ return arr;
+ }
+
+ static write(dataStream, value) {
+ dataStream.writeInt32(value.length);
+ value.forEach((innerValue) => {
+ FfiConverterTypeTodoEntry.write(dataStream, innerValue);
+ })
+ }
+
+ static computeSize(value) {
+ // The size of the length
+ let size = 4;
+ for (const innerValue of value) {
+ size += FfiConverterTypeTodoEntry.computeSize(innerValue);
+ }
+ return size;
+ }
+
+ static checkType(value) {
+ if (!Array.isArray(value)) {
+ throw new UniFFITypeError(`${value} is not an array`);
+ }
+ value.forEach((innerValue, idx) => {
+ try {
+ FfiConverterTypeTodoEntry.checkType(innerValue);
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart(`[${idx}]`);
+ }
+ throw e;
+ }
+ })
+ }
+}
+
+
+
+
+
+export function createEntryWith(todo) {
+
+ const liftResult = (result) => FfiConverterTypeTodoEntry.lift(result);
+ const liftError = (data) => FfiConverterTypeTodoError.lift(data);
+ const functionCall = () => {
+ try {
+ FfiConverterString.checkType(todo)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("todo");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 124, // todolist:uniffi_uniffi_todolist_fn_func_create_entry_with
+ FfiConverterString.lower(todo),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
+
+export function getDefaultList() {
+
+ const liftResult = (result) => FfiConverterOptionalTypeTodoList.lift(result);
+ const liftError = null;
+ const functionCall = () => {
+ return UniFFIScaffolding.callAsync(
+ 125, // todolist:uniffi_uniffi_todolist_fn_func_get_default_list
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
+
+export function setDefaultList(list) {
+
+ const liftResult = (result) => undefined;
+ const liftError = null;
+ const functionCall = () => {
+ try {
+ FfiConverterTypeTodoList.checkType(list)
+ } catch (e) {
+ if (e instanceof UniFFITypeError) {
+ e.addItemDescriptionPart("list");
+ }
+ throw e;
+ }
+ return UniFFIScaffolding.callAsync(
+ 126, // todolist:uniffi_uniffi_todolist_fn_func_set_default_list
+ FfiConverterTypeTodoList.lower(list),
+ )
+ }
+ try {
+ return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
+ } catch (error) {
+ return Promise.reject(error)
+ }
+}
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/moz.build b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/moz.build
new file mode 100644
index 0000000000..d5ff2d7cb6
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/moz.build
@@ -0,0 +1,24 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+FINAL_LIBRARY = "xul"
+
+components = [
+ "Arithmetic",
+ "CustomTypes",
+ "ExternalTypes",
+ "FixtureCallbacks",
+ "Geometry",
+ "Rondpoint",
+ "Sprites",
+ "Todolist",
+]
+
+EXTRA_JS_MODULES += [
+ "generated/Rust{}.sys.mjs".format(component) for component in components
+]
+
+XPCSHELL_TESTS_MANIFESTS += ["tests/xpcshell/xpcshell.toml"]
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_arithmetic.js b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_arithmetic.js
new file mode 100644
index 0000000000..a221abc39f
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_arithmetic.js
@@ -0,0 +1,48 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const Arithmetic = ChromeUtils.importESModule(
+ "resource://gre/modules/RustArithmetic.sys.mjs"
+);
+
+add_task(async function () {
+ Assert.ok(Arithmetic.IntegerOverflow);
+ Assert.equal(await Arithmetic.add(2, 4), 6);
+ Assert.equal(await Arithmetic.add(4, 8), 12);
+ // For other backends we would have this test:
+ // await Assert.rejects(
+ // Arithmetic.add(18446744073709551615, 1),
+ // Arithmetic.IntegerOverflow,
+ // "add() should throw IntegerOverflow")
+ //
+ // However, this doesn't work because JS number values are actually 64-bit
+ // floats, and that number is greater than the maximum "safe" integer.
+ //
+ // Instead, let's test that we reject numbers that are that big
+ await Assert.rejects(
+ Arithmetic.add(Number.MAX_SAFE_INTEGER + 1, 0),
+ /TypeError/,
+ "add() should throw TypeError when an input is > MAX_SAFE_INTEGER"
+ );
+
+ Assert.equal(await Arithmetic.sub(4, 2), 2);
+ Assert.equal(await Arithmetic.sub(8, 4), 4);
+ await Assert.rejects(
+ Arithmetic.sub(0, 1),
+ Arithmetic.IntegerOverflow,
+ "sub() should throw IntegerOverflow"
+ );
+
+ Assert.equal(await Arithmetic.div(8, 4), 2);
+ // Can't test this, because we don't allow Rust panics in FF
+ // Assert.rejects(
+ // Arithmetic.div(8, 0),
+ // (e) => Assert.equal(e, Arithmetic.UniFFIInternalError),
+ // "Divide by 0 should throw UniFFIInternalError")
+ //
+ Assert.ok(await Arithmetic.equal(2, 2));
+ Assert.ok(await Arithmetic.equal(4, 4));
+
+ Assert.ok(!(await Arithmetic.equal(2, 4)));
+ Assert.ok(!(await Arithmetic.equal(4, 8)));
+});
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_callbacks.js b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_callbacks.js
new file mode 100644
index 0000000000..67f0a167a8
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_callbacks.js
@@ -0,0 +1,47 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const { logEvenNumbers, logEvenNumbersMainThread } = ChromeUtils.importESModule(
+ "resource://gre/modules/RustFixtureCallbacks.sys.mjs"
+);
+
+class Logger {
+ constructor() {
+ this.messages = [];
+ this.finishedPromise = new Promise((resolve, reject) => {
+ this.finishedResolve = resolve;
+ this.finishedReject = reject;
+ });
+ }
+
+ log(message) {
+ this.messages.push(message);
+ }
+
+ finished() {
+ this.finishedResolve(true);
+ }
+
+ async waitForFinish() {
+ // Set a timeout to avoid hanging the tests if the Rust code fails to call finished().
+ do_timeout(2000, () =>
+ this.finishedReject("Timeout waiting for finished()")
+ );
+ return this.finishedPromise;
+ }
+}
+
+add_task(async function testLogEvenNumbers() {
+ async function runTest(logEvenNumbersFunc) {
+ const logger = new Logger();
+ logEvenNumbersFunc(logger, [1, 1, 2, 3, 5, 8, 13]);
+ await logger.waitForFinish();
+ Assert.deepEqual(logger.messages, [
+ "Saw even number: 2",
+ "Saw even number: 8",
+ ]);
+ }
+
+ await runTest(logEvenNumbers);
+ await runTest(logEvenNumbersMainThread);
+});
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_custom_types.js b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_custom_types.js
new file mode 100644
index 0000000000..cd26467494
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_custom_types.js
@@ -0,0 +1,13 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const CustomTypes = ChromeUtils.importESModule(
+ "resource://gre/modules/RustCustomTypes.sys.mjs"
+);
+
+add_task(async function () {
+ // JS right now doesn't treat custom types as anything but it's native counterparts
+ let demo = await CustomTypes.getCustomTypesDemo();
+ Assert.equal(demo.url, "http://example.com/");
+ Assert.equal(demo.handle, 123);
+});
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_external_types.js b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_external_types.js
new file mode 100644
index 0000000000..e2f985cde7
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_external_types.js
@@ -0,0 +1,16 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const ExternalTypes = ChromeUtils.importESModule(
+ "resource://gre/modules/RustExternalTypes.sys.mjs"
+);
+
+add_task(async function () {
+ const line = new ExternalTypes.Line(
+ new ExternalTypes.Point(0, 0, "p1"),
+ new ExternalTypes.Point(2, 1, "p2")
+ );
+ Assert.equal(await ExternalTypes.gradient(line), 0.5);
+
+ Assert.equal(await ExternalTypes.gradient(null), 0.0);
+});
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_geometry.js b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_geometry.js
new file mode 100644
index 0000000000..cdb552e4ef
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_geometry.js
@@ -0,0 +1,29 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const Geometry = ChromeUtils.importESModule(
+ "resource://gre/modules/RustGeometry.sys.mjs"
+);
+
+add_task(async function () {
+ const ln1 = new Geometry.Line(
+ new Geometry.Point({ coord_x: 0, coord_y: 0 }),
+ new Geometry.Point({ coord_x: 1, coord_y: 2 })
+ );
+ const ln2 = new Geometry.Line(
+ new Geometry.Point({ coord_x: 1, coord_y: 1 }),
+ new Geometry.Point({ coord_x: 2, coord_y: 2 })
+ );
+ const origin = new Geometry.Point({ coord_x: 0, coord_y: 0 });
+ Assert.ok(
+ (await Geometry.intersection({ start: ln1, end: ln2 })).equals(origin)
+ );
+ Assert.deepEqual(
+ await Geometry.intersection({ start: ln1, end: ln2 }),
+ origin
+ );
+ Assert.strictEqual(
+ await Geometry.intersection({ start: ln1, end: ln1 }),
+ null
+ );
+});
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_rondpoint.js b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_rondpoint.js
new file mode 100644
index 0000000000..8c673b2e92
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_rondpoint.js
@@ -0,0 +1,311 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const Rondpoint = ChromeUtils.importESModule(
+ "resource://gre/modules/RustRondpoint.sys.mjs"
+);
+
+const {
+ Dictionnaire,
+ Enumeration,
+ copieDictionnaire,
+ copieEnumeration,
+ copieEnumerations,
+ copieCarte,
+ EnumerationAvecDonnees,
+ switcheroo,
+ Retourneur,
+ DictionnaireNombresSignes,
+ DictionnaireNombres,
+ Stringifier,
+ Optionneur,
+ OptionneurDictionnaire,
+} = Rondpoint;
+add_task(async function () {
+ const dico = new Dictionnaire(Enumeration.DEUX, true, 0, 1235);
+ const copyDico = await copieDictionnaire(dico);
+ Assert.deepEqual(dico, copyDico);
+
+ Assert.equal(await copieEnumeration(Enumeration.DEUX), Enumeration.DEUX);
+ Assert.deepEqual(
+ await copieEnumerations([Enumeration.UN, Enumeration.DEUX]),
+ [Enumeration.UN, Enumeration.DEUX]
+ );
+ const obj = {
+ 0: new EnumerationAvecDonnees.Zero(),
+ 1: new EnumerationAvecDonnees.Un(1),
+ 2: new EnumerationAvecDonnees.Deux(2, "deux"),
+ };
+
+ Assert.deepEqual(await copieCarte(obj), obj);
+
+ const zero = new EnumerationAvecDonnees.Zero();
+ const one = new EnumerationAvecDonnees.Un(1);
+ const two = new EnumerationAvecDonnees.Deux(2);
+ Assert.notEqual(zero, one);
+ Assert.notEqual(one, two);
+
+ Assert.deepEqual(zero, new EnumerationAvecDonnees.Zero());
+ Assert.deepEqual(one, new EnumerationAvecDonnees.Un(1));
+ Assert.notDeepEqual(one, new EnumerationAvecDonnees.Un(4));
+
+ Assert.ok(await switcheroo(false));
+ // Test the roundtrip across the FFI.
+ // This shows that the values we send come back in exactly the same state as we sent them.
+ // i.e. it shows that lowering from JS and lifting into rust is symmetrical with
+ // lowering from rust and lifting into JS.
+
+ const rt = await Retourneur.init();
+
+ const affirmAllerRetour = async (arr, fn, equalFn) => {
+ for (const member of arr) {
+ if (equalFn) {
+ equalFn(await fn(member), member);
+ } else {
+ Assert.equal(await fn(member), member);
+ }
+ }
+ };
+
+ // Booleans
+ await affirmAllerRetour([true, false], rt.identiqueBoolean.bind(rt));
+
+ // Bytes
+ await affirmAllerRetour([-128, 127], rt.identiqueI8.bind(rt));
+ await affirmAllerRetour([0, 0xff], rt.identiqueU8.bind(rt));
+
+ // Shorts
+ await affirmAllerRetour([-32768, 32767], rt.identiqueI16.bind(rt));
+ await affirmAllerRetour([0, 0xffff], rt.identiqueU16.bind(rt));
+
+ // Ints
+ await affirmAllerRetour(
+ [0, 1, -1, -2147483648, 2147483647],
+ rt.identiqueI32.bind(rt)
+ );
+ await affirmAllerRetour([0, 0xffffffff], rt.identiqueU32.bind(rt));
+
+ // Longs
+ // NOTE: we cannot represent greater than `Number.MAX_SAFE_INTEGER`
+ await affirmAllerRetour(
+ [0, 1, -1, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER],
+ rt.identiqueI64.bind(rt)
+ );
+ await affirmAllerRetour(
+ [0, Number.MAX_SAFE_INTEGER],
+ rt.identiqueU64.bind(rt)
+ );
+
+ // Floats
+ const equalFloats = (a, b) => Assert.ok(Math.abs(a - b) <= Number.EPSILON);
+ await affirmAllerRetour(
+ [0.0, 0.5, 0.25, 1.5],
+ rt.identiqueFloat.bind(rt),
+ equalFloats
+ );
+ // Some float value's precision gets messed up, an example is 3.22, 100.223, etc
+ // await affirmAllerRetour([0.0, 0.5, 0.25, 1.5, 100.223], rt.identiqueFloat.bind(rt), equalFloats);
+
+ // Double (although on the JS side doubles are limited since they are also represented by Number)
+ await affirmAllerRetour(
+ [0.0, 0.5, 0.25, 1.5],
+ rt.identiqueDouble.bind(rt),
+ equalFloats
+ );
+
+ // Strings
+ await affirmAllerRetour(
+ [
+ "",
+ "abc",
+ "null\u0000byte",
+ "été",
+ "ښي لاس ته لوستلو لوستل",
+ "😻emoji 👨‍👧‍👦multi-emoji, 🇨🇭a flag, a canal, panama",
+ ],
+ rt.identiqueString.bind(rt)
+ );
+
+ await affirmAllerRetour(
+ [-1, 0, 1].map(n => new DictionnaireNombresSignes(n, n, n, n)),
+ rt.identiqueNombresSignes.bind(rt),
+ (a, b) => Assert.deepEqual(a, b)
+ );
+
+ await affirmAllerRetour(
+ [0, 1].map(n => new DictionnaireNombres(n, n, n, n)),
+ rt.identiqueNombres.bind(rt),
+ (a, b) => Assert.deepEqual(a, b)
+ );
+
+ // Test one way across the FFI.
+ //
+ // We send one representation of a value to lib.rs, and it transforms it into another, a string.
+ // lib.rs sends the string back, and then we compare here in js.
+ //
+ // This shows that the values are transformed into strings the same way in both js and rust.
+ // i.e. if we assume that the string return works (we test this assumption elsewhere)
+ // we show that lowering from js and lifting into rust has values that both js and rust
+ // both stringify in the same way. i.e. the same values.
+ //
+ // If we roundtripping proves the symmetry of our lowering/lifting from here to rust, and lowering/lifting from rust to here,
+ // and this convinces us that lowering/lifting from here to rust is correct, then
+ // together, we've shown the correctness of the return leg.
+ const st = await Stringifier.init();
+
+ const affirmEnchaine = async (arr, fn) => {
+ for (const member of arr) {
+ Assert.equal(await fn(member), String(member));
+ }
+ };
+
+ // Booleans
+ await affirmEnchaine([true, false], st.toStringBoolean.bind(st));
+
+ // Bytes
+ await affirmEnchaine([-128, 127], st.toStringI8.bind(st));
+ await affirmEnchaine([0, 0xff], st.toStringU8.bind(st));
+
+ // Shorts
+ await affirmEnchaine([-32768, 32767], st.toStringI16.bind(st));
+ await affirmEnchaine([0, 0xffff], st.toStringU16.bind(st));
+
+ // Ints
+ await affirmEnchaine(
+ [0, 1, -1, -2147483648, 2147483647],
+ st.toStringI32.bind(st)
+ );
+ await affirmEnchaine([0, 0xffffffff], st.toStringU32.bind(st));
+
+ // Longs
+ // NOTE: we cannot represent greater than `Number.MAX_SAFE_INTEGER`
+ await affirmEnchaine(
+ [0, 1, -1, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER],
+ st.toStringI64.bind(st)
+ );
+ await affirmEnchaine([0, Number.MAX_SAFE_INTEGER], st.toStringU64.bind(st));
+
+ // Floats
+ await affirmEnchaine([0.0, 0.5, 0.25, 1.5], st.toStringFloat.bind(st));
+
+ // Doubles
+ await affirmEnchaine([0.0, 0.5, 0.25, 1.5], st.toStringDouble.bind(st));
+
+ // Prove to ourselves that default arguments are being used.
+ // Step 1: call the methods without arguments, and check against the UDL.
+ const op = await Optionneur.init();
+
+ Assert.equal(await op.sinonString(), "default");
+
+ Assert.ok(!(await op.sinonBoolean()));
+
+ Assert.deepEqual(await op.sinonSequence(), []);
+
+ Assert.equal(await op.sinonNull(), null);
+ Assert.equal(await op.sinonZero(), 0);
+
+ // decimal integers
+ Assert.equal(await op.sinonI8Dec(), -42);
+ Assert.equal(await op.sinonU8Dec(), 42);
+ Assert.equal(await op.sinonI16Dec(), 42);
+ Assert.equal(await op.sinonU16Dec(), 42);
+ Assert.equal(await op.sinonI32Dec(), 42);
+ Assert.equal(await op.sinonU32Dec(), 42);
+ Assert.equal(await op.sinonI64Dec(), 42);
+ Assert.equal(await op.sinonU64Dec(), 42);
+
+ // hexadecimal integers
+ Assert.equal(await op.sinonI8Hex(), -0x7f);
+ Assert.equal(await op.sinonU8Hex(), 0xff);
+ Assert.equal(await op.sinonI16Hex(), 0x7f);
+ Assert.equal(await op.sinonU16Hex(), 0xffff);
+ Assert.equal(await op.sinonI32Hex(), 0x7fffffff);
+ Assert.equal(await op.sinonU32Hex(), 0xffffffff);
+ // The following are too big to be represented by js `Number`
+ // Assert.equal(await op.sinonI64Hex(), 0x7fffffffffffffff);
+ // Assert.equal(await op.sinonU64Hex(), 0xffffffffffffffff);
+
+ // octal integers
+ Assert.equal(await op.sinonU32Oct(), 0o755);
+
+ // floats
+ Assert.equal(await op.sinonF32(), 42.0);
+ Assert.equal(await op.sinonF64(), 42.1);
+
+ // enums
+ Assert.equal(await op.sinonEnum(), Enumeration.TROIS);
+
+ // Step 2. Convince ourselves that if we pass something else, then that changes the output.
+ // We have shown something coming out of the sinon methods, but without eyeballing the Rust
+ // we can't be sure that the arguments will change the return value.
+
+ await affirmAllerRetour(["foo", "bar"], op.sinonString.bind(op));
+ await affirmAllerRetour([true, false], op.sinonBoolean.bind(op));
+ await affirmAllerRetour([["a", "b"], []], op.sinonSequence.bind(op), (a, b) =>
+ Assert.deepEqual(a, b)
+ );
+
+ // Optionals
+ await affirmAllerRetour(["0", "1"], op.sinonNull.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonZero.bind(op));
+
+ // integers
+ await affirmAllerRetour([0, 1], op.sinonU8Dec.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonI8Dec.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonU16Dec.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonI16Dec.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonU32Dec.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonI32Dec.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonU64Dec.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonI64Dec.bind(op));
+
+ await affirmAllerRetour([0, 1], op.sinonU8Hex.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonI8Hex.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonU16Hex.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonI16Hex.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonU32Hex.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonI32Hex.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonU64Hex.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonI64Hex.bind(op));
+ await affirmAllerRetour([0, 1], op.sinonU32Oct.bind(op));
+
+ // Floats
+ await affirmAllerRetour([0.0, 1.0], op.sinonF32.bind(op));
+ await affirmAllerRetour([0.0, 1.0], op.sinonF64.bind(op));
+
+ // enums
+ await affirmAllerRetour(
+ [Enumeration.UN, Enumeration.DEUX, Enumeration.TROIS],
+ op.sinonEnum.bind(op)
+ );
+
+ // Testing defaulting properties in record types.
+ const defaultes = new OptionneurDictionnaire();
+ const explicite = new OptionneurDictionnaire(
+ -8,
+ 8,
+ -16,
+ 0x10,
+ -32,
+ 32,
+ -64,
+ 64,
+ 4.0,
+ 8.0,
+ true,
+ "default",
+ [],
+ Enumeration.DEUX,
+ null
+ );
+
+ Assert.deepEqual(defaultes, explicite);
+
+ // …and makes sure they travel across and back the FFI.
+
+ await affirmAllerRetour(
+ [defaultes, explicite],
+ rt.identiqueOptionneurDictionnaire.bind(rt),
+ (a, b) => Assert.deepEqual(a, b)
+ );
+});
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_sprites.js b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_sprites.js
new file mode 100644
index 0000000000..3feb2fd34d
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_sprites.js
@@ -0,0 +1,28 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const Sprites = ChromeUtils.importESModule(
+ "resource://gre/modules/RustSprites.sys.mjs"
+);
+
+add_task(async function () {
+ Assert.ok(Sprites.Sprite);
+
+ const sempty = await Sprites.Sprite.init(null);
+ Assert.deepEqual(await sempty.getPosition(), new Sprites.Point(0, 0));
+
+ const s = await Sprites.Sprite.init(new Sprites.Point(0, 1));
+ Assert.deepEqual(await s.getPosition(), new Sprites.Point(0, 1));
+
+ s.moveTo(new Sprites.Point(1, 2));
+ Assert.deepEqual(await s.getPosition(), new Sprites.Point(1, 2));
+
+ s.moveBy(new Sprites.Vector(-4, 2));
+ Assert.deepEqual(await s.getPosition(), new Sprites.Point(-3, 4));
+
+ const srel = await Sprites.Sprite.newRelativeTo(
+ new Sprites.Point(0, 1),
+ new Sprites.Vector(1, 1.5)
+ );
+ Assert.deepEqual(await srel.getPosition(), new Sprites.Point(1, 2.5));
+});
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_todolist.js b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_todolist.js
new file mode 100644
index 0000000000..dac26d2be1
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_todolist.js
@@ -0,0 +1,71 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const { TodoList, TodoEntry, getDefaultList, setDefaultList } =
+ ChromeUtils.importESModule("resource://gre/modules/RustTodolist.sys.mjs");
+
+add_task(async function () {
+ const todo = await TodoList.init();
+ const entry = new TodoEntry("Write bindings for strings in records");
+
+ await todo.addItem("Write JS bindings");
+ Assert.equal(await todo.getLast(), "Write JS bindings");
+
+ await todo.addItem("Write tests for bindings");
+ Assert.equal(await todo.getLast(), "Write tests for bindings");
+
+ await todo.addEntry(entry);
+ Assert.equal(await todo.getLast(), "Write bindings for strings in records");
+ Assert.equal(
+ (await todo.getLastEntry()).text,
+ "Write bindings for strings in records"
+ );
+ Assert.ok((await todo.getLastEntry()).equals(entry));
+
+ await todo.addItem(
+ "Test Ünicode hàndling without an entry can't believe I didn't test this at first 🤣"
+ );
+ Assert.equal(
+ await todo.getLast(),
+ "Test Ünicode hàndling without an entry can't believe I didn't test this at first 🤣"
+ );
+
+ const entry2 = new TodoEntry(
+ "Test Ünicode hàndling in an entry can't believe I didn't test this at first 🤣"
+ );
+ await todo.addEntry(entry2);
+ Assert.equal(
+ (await todo.getLastEntry()).text,
+ "Test Ünicode hàndling in an entry can't believe I didn't test this at first 🤣"
+ );
+
+ const todo2 = await TodoList.init();
+ Assert.notEqual(todo, todo2);
+ Assert.notStrictEqual(todo, todo2);
+
+ Assert.strictEqual(await getDefaultList(), null);
+
+ await setDefaultList(todo);
+ Assert.deepEqual(
+ await todo.getItems(),
+ await (await getDefaultList()).getItems()
+ );
+
+ todo2.makeDefault();
+ Assert.deepEqual(
+ await todo2.getItems(),
+ await (await getDefaultList()).getItems()
+ );
+
+ await todo.addItem("Test liveness after being demoted from default");
+ Assert.equal(
+ await todo.getLast(),
+ "Test liveness after being demoted from default"
+ );
+
+ todo2.addItem("Test shared state through local vs default reference");
+ Assert.equal(
+ await (await getDefaultList()).getLast(),
+ "Test shared state through local vs default reference"
+ );
+});
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_type_checking.js b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_type_checking.js
new file mode 100644
index 0000000000..bfeb07c82b
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/test_type_checking.js
@@ -0,0 +1,123 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const Arithmetic = ChromeUtils.importESModule(
+ "resource://gre/modules/RustArithmetic.sys.mjs"
+);
+const Geometry = ChromeUtils.importESModule(
+ "resource://gre/modules/RustGeometry.sys.mjs"
+);
+const TodoList = ChromeUtils.importESModule(
+ "resource://gre/modules/RustTodolist.sys.mjs"
+);
+const Rondpoint = ChromeUtils.importESModule(
+ "resource://gre/modules/RustRondpoint.sys.mjs"
+);
+const { UniFFITypeError } = ChromeUtils.importESModule(
+ "resource://gre/modules/UniFFI.sys.mjs"
+);
+
+add_task(async function testFunctionArguments() {
+ await Assert.rejects(
+ Arithmetic.add(2),
+ UniFFITypeError,
+ "add() call missing argument"
+ );
+ Assert.throws(
+ () => new Geometry.Point(0.0),
+ UniFFITypeError,
+ "Point constructor missing argument"
+ );
+});
+
+add_task(async function testObjectPointers() {
+ const todo = await TodoList.TodoList.init();
+ const stringifier = await Rondpoint.Stringifier.init();
+ await todo.getEntries(); // OK
+ todo[TodoList.UnitTestObjs.uniffiObjectPtr] =
+ stringifier[Rondpoint.UnitTestObjs.uniffiObjectPtr];
+
+ await Assert.rejects(
+ todo.getEntries(), // the pointer is incorrect, should throw
+ /Bad pointer type/,
+ "getEntries() with wrong pointer type"
+ );
+});
+
+add_task(async function testEnumTypeCheck() {
+ await Assert.rejects(
+ Rondpoint.copieEnumeration("invalid"), // Not an integer value
+ /e:/, // Ensure exception message includes the argument name
+ "copieEnumeration() with non-Enumeration value should throw"
+ );
+ await Assert.rejects(
+ Rondpoint.copieEnumeration(0), // Integer, but doesn't map to a variant
+ /e:/, // Ensure exception message includes the argument name
+ "copieEnumeration() with non-Enumeration value should throw"
+ );
+ await Assert.rejects(
+ Rondpoint.copieEnumeration(4), // Integer, but doesn't map to a variant
+ /e:/, // Ensure exception message includes the argument name
+ "copieEnumeration() with non-Enumeration value should throw"
+ );
+});
+
+add_task(async function testRecordTypeCheck() {
+ await Assert.rejects(
+ Geometry.gradient(123), // Not a Line object
+ UniFFITypeError,
+ "gradient with non-Line object should throw"
+ );
+
+ await Assert.rejects(
+ Geometry.gradient({
+ start: {
+ coordX: 0.0,
+ coordY: 0.0,
+ },
+ // missing the end field
+ }),
+ /ln.end/, // Ensure exception message includes the argument name
+ "gradient with Line object with missing end field should throw"
+ );
+});
+
+add_task(async function testOptionTypeCheck() {
+ const optionneur = await Rondpoint.Optionneur.init();
+ await Assert.rejects(
+ optionneur.sinonNull(0),
+ UniFFITypeError,
+ "sinonNull with non-string should throw"
+ );
+});
+
+add_task(async function testSequenceTypeCheck() {
+ const todo = await TodoList.TodoList.init();
+ await Assert.rejects(
+ todo.addEntries("not a list"),
+ UniFFITypeError,
+ "addEntries with non-list should throw"
+ );
+
+ await Assert.rejects(
+ todo.addEntries(["not TodoEntry"]),
+ /entries\[0]/,
+ "addEntries with non TodoEntry item should throw"
+ );
+});
+
+add_task(async function testMapTypeCheck() {
+ await Assert.rejects(
+ Rondpoint.copieCarte("not a map"),
+ UniFFITypeError,
+ "copieCarte with a non-map should throw"
+ );
+
+ await Assert.rejects(
+ Rondpoint.copieCarte({ x: 1 }),
+ /c\[x]/,
+ "copieCarte with a wrong value type should throw"
+ );
+
+ // TODO: test key types once we implement https://bugzilla.mozilla.org/show_bug.cgi?id=1809459
+});
diff --git a/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/xpcshell.toml b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/xpcshell.toml
new file mode 100644
index 0000000000..76814ff199
--- /dev/null
+++ b/toolkit/components/uniffi-bindgen-gecko-js/fixtures/tests/xpcshell/xpcshell.toml
@@ -0,0 +1,19 @@
+[DEFAULT]
+
+["test_arithmetic.js"]
+
+["test_callbacks.js"]
+
+["test_custom_types.js"]
+
+["test_external_types.js"]
+
+["test_geometry.js"]
+
+["test_rondpoint.js"]
+
+["test_sprites.js"]
+
+["test_todolist.js"]
+
+["test_type_checking.js"]