runWithCheckingAsync<R> function

Future<R> runWithCheckingAsync<R>({
  1. required bool preCondition(),
  2. required Future<R> operation(),
  3. required bool postCondition(
    1. R result
    ),
  4. ContractCheckingMode checkingMode = .assertionsOnly,
})

Runs operation after checking preCondition and checks its result.

In ContractCheckingMode.assertionsOnly, failed conditions trigger Dart assertions and therefore depend on assertions being enabled. In ContractCheckingMode.alwaysThrow, failed conditions throw ContractViolationError. Defaults to ContractCheckingMode.assertionsOnly. Set checkingMode to select the checking behavior. When assertions are disabled, the condition callbacks are not invoked in ContractCheckingMode.assertionsOnly.

Exceptions thrown by a condition or by operation propagate unchanged.

Implementation

Future<R> runWithCheckingAsync<R>({
  required bool Function() preCondition,
  required Future<R> Function() operation,
  required bool Function(R result) postCondition,
  ContractCheckingMode checkingMode = .assertionsOnly,
}) async {
  switch (checkingMode) {
    case .assertionsOnly:
      assert(preCondition(), 'Precondition violated');

      final result = await operation();

      assert(postCondition(result), 'Postcondition violated');

      return result;

    case .alwaysThrow:
      if (!preCondition()) {
        throw ContractViolationError(
          kind: .preCondition,
          message: 'Precondition violated',
        );
      }

      final result = await operation();

      if (!postCondition(result)) {
        throw ContractViolationError(
          kind: .postCondition,
          message: 'Postcondition violated',
        );
      }

      return result;
  }
}