uniffiRustCallAsync<T, F> function

Future<T> uniffiRustCallAsync<T, F>(
  1. Pointer<Void> rustFutureFunc(),
  2. void pollFunc(
    1. Pointer<Void>,
    2. Pointer<NativeFunction<UniffiRustFutureContinuationCallback>>,
    3. Pointer<Void>
    ),
  3. F completeFunc(
    1. Pointer<Void>,
    2. Pointer<RustCallStatus>
    ),
  4. void freeFunc(
    1. Pointer<Void>
    ),
  5. T liftFunc(
    1. F
    ), [
  6. UniffiRustCallStatusErrorHandler? errorHandler,
])

Implementation

Future<T> uniffiRustCallAsync<T, F>(
  Pointer<Void> Function() rustFutureFunc,
  void Function(
          Pointer<Void>,
          Pointer<NativeFunction<UniffiRustFutureContinuationCallback>>,
          Pointer<Void>)
      pollFunc,
  F Function(Pointer<Void>, Pointer<RustCallStatus>) completeFunc,
  void Function(Pointer<Void>) freeFunc,
  T Function(F) liftFunc, [
  UniffiRustCallStatusErrorHandler? errorHandler,
]) async {
  final rustFuture = rustFutureFunc();
  final completer = Completer<int>();

  late final NativeCallable<UniffiRustFutureContinuationCallback> callback;

  void poll() {
    pollFunc(
      rustFuture,
      callback.nativeFunction,
      Pointer<Void>.fromAddress(0),
    );
  }

  void onResponse(int _idx, int pollResult) {
    if (pollResult == UNIFFI_RUST_FUTURE_POLL_READY) {
      completer.complete(pollResult);
    } else {
      poll();
    }
  }

  callback =
      NativeCallable<UniffiRustFutureContinuationCallback>.listener(onResponse);

  try {
    poll();
    await completer.future;
    callback.close();

    final status = calloc<RustCallStatus>();
    try {
      final result = completeFunc(rustFuture, status);

      return liftFunc(result);
    } finally {
      calloc.free(status);
    }
  } finally {
    freeFunc(rustFuture);
  }
}