fusing<TResource extends FDisposable, TResult> function

Future<TResult> fusing<TResource extends FDisposable, TResult>(
  1. FExecutionContext executionContext,
  2. FusingResourceInitializer<TResource> resourceFactory,
  3. FusingWorker<TResource, TResult> worker
)

Implementation

Future<TResult> fusing<TResource extends FDisposable, TResult>(
  final FExecutionContext executionContext,
  final FusingResourceInitializer<TResource> resourceFactory,
  final FusingWorker<TResource, TResult> worker,
) {
  Future<TResult> workerExecutor(
    final FExecutionContext workerExecutorCancellactonToken,
    TResource disposableResource,
  ) async {
    if (disposableResource is FInitable) {
      await disposableResource.init(executionContext);
    }
    try {
      final workerResult =
          worker(workerExecutorCancellactonToken, disposableResource);
      if (workerResult is Future<TResult>) {
        return await workerResult;
      } else {
        return workerResult;
      }
    } finally {
      await disposableResource.dispose();
    }
  }

  Future<TResult> workerExecutorFacade(
      final FutureOr<TResource> disposableObject) {
    if (disposableObject is Future<TResource>) {
      return disposableObject.then(
        (disposableInstance) =>
            workerExecutor(executionContext, disposableInstance),
      );
    } else {
      return workerExecutor(executionContext, disposableObject);
    }
  }

  final FutureOr<TResource> resource = resourceFactory(executionContext);
  return workerExecutorFacade(resource);
}