/* * 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/ */ import { Cursor } from "./cursor.ts"; import { type FfiConverter, FfiConverterUInt64, type RustBufferAllocator, } from "./ffi-converters.ts"; import { type UniffiByteArray } from "./ffi-types.ts"; import { type UniffiHandle, UniffiHandleMap, defaultUniffiHandle, } from "./handle-map.ts"; import { CALL_ERROR, CALL_UNEXPECTED_ERROR } from "./rust-call.ts"; const handleConverter = FfiConverterUInt64; export class FfiConverterCallback implements FfiConverter { constructor(private handleMap = new UniffiHandleMap()) {} lift(value: UniffiHandle): T { return this.handleMap.get(value); } lower(value: T, _alloc: RustBufferAllocator): UniffiHandle { return this.handleMap.insert(value); } readFromCursor(c: Cursor): T { return this.lift(handleConverter.readFromCursor(c)); } writeIntoCursor(value: T, c: Cursor): void { handleConverter.writeIntoCursor(this.handleMap.insert(value), c); } allocationSize(value: T): number { return handleConverter.allocationSize(defaultUniffiHandle); } clone(handle: UniffiHandle): UniffiHandle { return this.handleMap.clone(handle); } drop(handle: UniffiHandle): T | undefined { return this.handleMap.remove(handle); } } export type UniffiReferenceHolder = { pointee: T }; export function uniffiTraitInterfaceCall( makeCall: () => T, handleSuccess: (v: T) => void, handleError: ( callStatus: /*i8*/ number, errorBuffer: UniffiByteArray, ) => void, lowerString: (s: string, alloc: RustBufferAllocator) => UniffiByteArray, alloc: RustBufferAllocator, ) { try { handleSuccess(makeCall()); } catch (e: any) { handleError(CALL_UNEXPECTED_ERROR, lowerString(e.toString(), alloc)); } } export function uniffiTraitInterfaceCallWithError( makeCall: () => T, handleSuccess: (v: T) => void, handleError: ( callStatus: /*i8*/ number, errorBuffer: UniffiByteArray, ) => void, isErrorType: (e: any) => e is E, lowerError: (err: E, alloc: RustBufferAllocator) => UniffiByteArray, lowerString: (s: string, alloc: RustBufferAllocator) => UniffiByteArray, alloc: RustBufferAllocator, ): void { try { handleSuccess(makeCall()); } catch (e: any) { // Hermes' prototype chain seems buggy, so we need to make our // own arrangements if (isErrorType(e)) { handleError(CALL_ERROR, lowerError(e, alloc)); } else { handleError(CALL_UNEXPECTED_ERROR, lowerString(e.toString(), alloc)); } } }