From f36e0b51e0e10d951922a2abc5703a87bb97b550 Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Wed, 23 Nov 2022 19:13:04 -0500 Subject: [PATCH] feat(type): add Result extension on FutureOr type (close #40) --- .../lib/src/either/either_base.dart | 3 + .../lib/src/either/future_or_result.dart | 126 ++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 packages/wyatt_type_utils/lib/src/either/future_or_result.dart diff --git a/packages/wyatt_type_utils/lib/src/either/either_base.dart b/packages/wyatt_type_utils/lib/src/either/either_base.dart index 651132ef..f8b3546f 100644 --- a/packages/wyatt_type_utils/lib/src/either/either_base.dart +++ b/packages/wyatt_type_utils/lib/src/either/either_base.dart @@ -16,7 +16,10 @@ // // ignore_for_file: avoid_positional_boolean_parameters +import 'dart:async'; + part 'future_result.dart'; +part 'future_or_result.dart'; part 'result.dart'; part 'option.dart'; diff --git a/packages/wyatt_type_utils/lib/src/either/future_or_result.dart b/packages/wyatt_type_utils/lib/src/either/future_or_result.dart new file mode 100644 index 00000000..8cf0e652 --- /dev/null +++ b/packages/wyatt_type_utils/lib/src/either/future_or_result.dart @@ -0,0 +1,126 @@ +// Copyright (C) 2022 WYATT GROUP +// Please see the AUTHORS file for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +part of 'either_base.dart'; + +extension FutureOrResultExtension on FutureOr> { + /// Represents the left side of [Result] class. + Future get isOk => Future.value(this).then((result) => result.isOk); + + /// Represents the right side of [Result] class. + Future get isErr => Future.value(this).then((result) => result.isErr); + + /// Get [U] value, may throw an exception. + Future unwrap() => + Future.value(this).then((result) => result.unwrap()); + + /// Get **async** [U] value, may throw an exception. + /// + /// With nullable, `Future(Future(U)) == Future(U)` + Future unwrapAsync() => + Future.value(this).then((result) => result.unwrapAsync()); + + /// Fold [Ok] and [Err] into the value of one type + Future fold( + U Function(T value) valueTransformer, + U Function(E error) errorTransformer, + ) => + Future.value(this) + .then((result) => result.fold(valueTransformer, errorTransformer)); + + /// Fold [Ok] and [Err] **asynchronously** into the value of one type + Future foldAsync( + Future Function(T value) valueTransformer, + Future Function(E error) errorTransformer, + ) => + Future.value(this).then( + (result) => result.foldAsync( + valueTransformer, + errorTransformer, + ), + ); + + /// Swap [Ok] and [Err] + Future> swap() => + Future.value(this).then((result) => result.swap()); + + /// Returns [res] if the [Result] is [Ok], otherwise returns + /// the [Err] value of this. + Future> and(Result res) => + Future.value(this).then((result) => result.and(res)); + + /// Returns [res] if the [Result] is [Err], otherwise returns + /// the [Ok] value of this. + Future> or(Result res) => + Future.value(this).then((result) => result.or(res)); + + /// Returns true if the result is an [Ok] or [Err] value containing + /// the given value/error. + Future contains(U x) => + Future.value(this).then((result) => result.contains(x)); + + /// Returns the contained [Ok] value. Throw [ResultException] on [Err] with + /// its content. + Future expect(String msg) => + Future.value(this).then((result) => result.expect(msg)); + + /// Returns the contained [Err] value. Throw [ResultException] on [Ok] with + /// its content. + Future expectErr(String msg) => + Future.value(this).then((result) => result.expectErr(msg)); + + /// Maps a [Result] to [Result] by applying a function to a + /// contained [Ok] value, leaving an [Err] value untouched. + Future> map(U Function(T value) mapper) => + Future.value(this).then((result) => result.map(mapper)); + + /// Maps a [Result] to [Result] by applying an **async** function + /// to a contained [Ok] value, leaving an [Err] value untouched. + Future> mapAsync(Future Function(T value) mapper) => + Future.value(this).then((result) => result.mapAsync(mapper)); + + /// Maps a [Result] to [Result] by applying a function to a + /// contained [Err] value, leaving an [Ok] value untouched. + Future> mapErr(F Function(E error) mapper) => + Future.value(this).then((result) => result.mapErr(mapper)); + + /// Maps a [Result] to [Result] by applying an **async** function + /// to a contained [Err] value, leaving an [Ok] value untouched. + Future> mapErrAsync(Future Function(E error) mapper) => + Future.value(this).then((result) => result.mapErrAsync(mapper)); + + /// Transforms a [Result] to [Result] by applying functions to + /// contained [Ok] and [Err] values. + Future> either( + U Function(T value) valueTransformer, + F Function(E error) errorTransformer, + ) => + Future.value(this) + .then((result) => result.either(valueTransformer, errorTransformer)); + + /// Transforms a [Result] to [Result] by applying **async** + /// functions to contained [Ok] and [Err] values. + Future> eitherAsync( + Future Function(T value) valueTransformer, + Future Function(E error) errorTransformer, + ) => + Future.value(this).then( + (result) => result.eitherAsync( + valueTransformer, + errorTransformer, + ), + ); +} -- 2.47.2