cond method

Resolvable<T> cond(
  1. bool test(
    1. T value
    )
)

Returns the value of the Pod when the test returns true.

The internal listener is held strongly via pinListener so dropping the returned Resolvable without awaiting it cannot cause the listener to be garbage collected before test succeeds.

Failure modes — all surface as Err on the returned Resolvable rather than crashing the caller or hanging forever:

  • Pod disposed before test ever matchesErr(StateError(...)).
  • test throws (sync first call or any later notify) → Err(thrown error).

Implementation

Resolvable<T> cond(bool Function(T value) test) {
  // Bail out on a disposed pod: addStrongRefListener is a release-mode
  // no-op on a disposed notifier, so subscribing would mean the
  // SafeCompleter never resolves and the caller's await hangs.
  if (isDisposed) {
    return Sync.err(
      Err(StateError('Cannot call cond() on a disposed pod')),
    );
  }
  final finisher = SafeCompleter<T>();
  late final VoidCallback check;
  check = () {
    // A throwing predicate must not leave the completer stuck — convert
    // throws into an Err on the returned Resolvable.
    try {
      if (test(value)) {
        finisher.complete(value).end();
        _pendingConds?.remove(finisher);
        unpinListener(check);
        removeListener(check);
      }
    } catch (e, s) {
      finisher.resolve(Sync.err(Err(e, stackTrace: s))).end();
      _pendingConds?.remove(finisher);
      unpinListener(check);
      removeListener(check);
    }
  };
  check();
  if (finisher.isCompleted) {
    return finisher.resolvable();
  }
  // A side-effecting predicate may have disposed the pod during the
  // sync check above. Without this guard, subscribing would be a no-op
  // and the finisher would never resolve.
  if (isDisposed) {
    finisher
        .resolve(
          Sync.err(
            Err(
              StateError(
                'Pod was disposed during cond() predicate execution',
              ),
            ),
          ),
        )
        .end();
    return finisher.resolvable();
  }
  (_pendingConds ??= <SafeCompleter<T>>{}).add(finisher);
  pinListener(check);
  addStrongRefListener(strongRefListener: check);
  return finisher.resolvable();
}