transf<R extends Object> method

SafeCompleter<R> transf<R extends Object>([
  1. @noFutures @sendable R noFutures(
    1. T e
    )?
])

Creates a new SafeCompleter by transforming the future value of this one.

When this completer finishes, its value will be passed to the noFutures function (or cast if null), and the result will be used to resolve the new completer.

Implementation

SafeCompleter<R> transf<R extends Object>([
  @noFutures @sendable R Function(T e)? noFutures,
]) {
  final newCompleter = SafeCompleter<R>();
  resolvable().then((e) {
    try {
      final result = noFutures != null ? noFutures(e) : (e as R);
      newCompleter.complete(result).end();
    } on Err catch (err) {
      // Preserve a user-thrown Err's statusCode/breadcrumbs verbatim
      // rather than re-wrapping it inside another Err.
      newCompleter.resolve(Sync.err(err.transfErr<R>())).end();
    } catch (error, stackTrace) {
      newCompleter
          .resolve(Sync.err(Err<R>(error, stackTrace: stackTrace)))
          .end();
    }
    return e;
  })
      // Forward errors from the source completer. Without this, an Err
      // source would silently leave `newCompleter` dangling forever —
      // `then((e) => ...)` only fires on Ok, so the new completer would
      // never be resolved and any awaiter would hang.
      .ifErr((_, err) {
    if (!newCompleter.isCompleted) {
      newCompleter.resolve(Sync.err(err.transfErr<R>())).end();
    }
  }).end();
  return newCompleter;
}