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 2f06414e..aef28c3a 100644
--- a/packages/wyatt_type_utils/lib/src/either/either_base.dart
+++ b/packages/wyatt_type_utils/lib/src/either/either_base.dart
@@ -1,26 +1,21 @@
-// // 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 .
-
-// // ignore_for_file: avoid_positional_boolean_parameters
+// Copyright (C) 2024 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 .
import 'dart:async';
-part 'future_result.dart';
-part 'future_or_result.dart';
-part 'result.dart';
part 'option.dart';
mixin _Left on _EitherBase {}
@@ -35,7 +30,9 @@ class _EitherBaseException implements Exception {
String toString() => '_EitherException: $message';
}
+@Deprecated('Use Dart pattern matching instead')
abstract class _EitherBase {
+ @Deprecated('Use Dart pattern matching instead')
const _EitherBase();
bool get _isLeft => this is _Left;
@@ -56,20 +53,20 @@ abstract class _EitherBase {
if (U == LeftType) {
return _fold(
(value) => value,
- (right) => throw const ResultException(
+ (right) => throw Exception(
'Illegal use. You should check left value before calling',
),
) as U;
}
if (U == RightType) {
return _fold(
- (left) => throw const ResultException(
+ (left) => throw Exception(
'Illegal use. You should check right value before calling',
),
(value) => value,
) as U;
}
- throw ResultException(
+ throw Exception(
'Illegal use. You should use $LeftType or $RightType type',
);
}
@@ -78,20 +75,20 @@ abstract class _EitherBase {
if (U == LeftType) {
return _foldAsync(
Future.value,
- (right) => throw const ResultException(
+ (right) => throw Exception(
'Illegal use. You should check left value before calling',
),
) as Future;
}
if (U == RightType) {
return _foldAsync(
- (left) => throw const ResultException(
+ (left) => throw Exception(
'Illegal use. You should check right value before calling',
),
Future.value,
) as Future;
}
- throw ResultException(
+ throw Exception(
'Illegal use. You should use $LeftType or $RightType type',
);
}
diff --git a/packages/wyatt_type_utils/lib/src/either/option.dart b/packages/wyatt_type_utils/lib/src/either/option.dart
index 3502984f..f5bb8f89 100644
--- a/packages/wyatt_type_utils/lib/src/either/option.dart
+++ b/packages/wyatt_type_utils/lib/src/either/option.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2024 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -41,8 +41,10 @@ class OptionException extends _EitherBaseException {
/// if value not present) and ifPresent() (execute a block of code if the
/// value is present).
/// {@endtemplate}
+@Deprecated('Use Dart pattern matching instead')
abstract class Option extends _EitherBase {
/// {@macro option}
+ @Deprecated('Use Dart pattern matching instead')
const Option._();
/// Represents the left side of [Option] class.
diff --git a/packages/wyatt_type_utils/lib/src/either/result.dart b/packages/wyatt_type_utils/lib/src/either/result.dart
deleted file mode 100644
index c4d03189..00000000
--- a/packages/wyatt_type_utils/lib/src/either/result.dart
+++ /dev/null
@@ -1,325 +0,0 @@
-// 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 .
-
-// ignore_for_file: avoid_positional_boolean_parameters
-
-part of 'either_base.dart';
-
-/// {@template result_exception}
-/// [ResultException] is sometimes threw by [Result] objects.
-///
-/// ```dart
-/// throw ResultException('Emergency failure!');
-/// ```
-/// {@endtemplate}
-class ResultException extends _EitherBaseException {
- /// {@macro result_exception}
- const ResultException(super.message);
-
- @override
- String toString() => 'ResultException: $message';
-}
-
-/// {@template result}
-/// [Result] type is coming from functional languages where exceptions are
-/// (rightfully) considered a side-effect, and therefore not appropriate to
-/// pass domain errors. Mind the difference between different kinds of errors:
-/// Some of them belong to domain, others don't.
-///
-/// *E.g. null reference exception or index out of bounds
-/// are not related to domain - they rather indicate a defect.*
-///
-/// Either is defined as a generic type with two branches
-/// - success with [T]
-/// - failure with [E]
-///
-/// It can appear in two forms, where
-/// it contains an object of [Ok], or where it contains an object
-/// of [Err]. It cannot appear in both states at once, or in none of them.
-/// Therefore, if one possesses an [Result] instance, it either contains a
-/// successfully produced result, or contains an error object.
-/// {@endtemplate}
-abstract class Result extends _EitherBase {
- /// {@macro result}
- const Result._();
-
- /// Represents the left side of [Result] class.
- bool get isOk => _isLeft;
-
- /// Represents the right side of [Result] class.
- bool get isErr => _isRight;
-
- /// Get nullable [Ok] value, and discarding the error, if any.
- T? get ok => _left;
-
- /// Get nullable [Err] value, and discarding the success value, if any.
- E? get err => _right;
-
- /// Get [U] value, may throw an exception.
- U unwrap() => _unwrap();
-
- /// Get **async** [U] value, may throw an exception.
- Future unwrapAsync() => _unwrapAsync();
-
- /// Fold [Ok] and [Err] into the value of one type
- U fold(
- U Function(T value) valueTransformer,
- U Function(E error) errorTransformer,
- ) =>
- _fold(
- (left) => valueTransformer(left),
- (right) => errorTransformer(right),
- );
-
- /// Fold [Ok] and [Err] **asynchronously** into the value of one type
- Future foldAsync(
- Future Function(T value) valueTransformer,
- Future Function(E error) errorTransformer,
- ) =>
- _foldAsync(
- (left) => valueTransformer(left),
- (right) => errorTransformer(right),
- );
-
- /// Swap [Ok] and [Err]
- Result swap() => fold(Err.new, Ok.new);
-
- /// Returns [res] if the [Result] is [Ok], otherwise returns
- /// the [Err] value of this.
- Result and(Result res) => _and(res) as Result;
-
- /// Returns [res] if the [Result] is [Err], otherwise returns
- /// the [Ok] value of this.
- Result or(Result res) => _or(res) as Result;
-
- /// Returns true if the result is an [Ok] or [Err] value containing
- /// the given value/error.
- bool contains(U x) => _contains(x);
-
- /// Returns the contained [Ok] value. Throw [ResultException] on [Err] with
- /// its content.
- T expect(String msg) => _expect(msg);
-
- /// Returns the contained [Err] value. Throw [ResultException] on [Ok] with
- /// its content.
- E expectErr(String msg) => _expectErr(msg);
-
- /// Maps a [Result] to [Result] by applying a function to a
- /// contained [Ok] value, leaving an [Err] value untouched.
- Result map(U Function(T value) mapper) =>
- _map(mapper) as Result;
-
- /// 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) =>
- _mapAsync(mapper) as Future>;
-
- /// Maps a [Result] to [Result] by applying a function to a
- /// contained [Err] value, leaving an [Ok] value untouched.
- Result mapErr(F Function(E error) mapper) =>
- _mapErr(mapper) as Result;
-
- /// 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) =>
- _mapErrAsync(mapper) as Future>;
-
- /// Transforms a [Result] to [Result] by applying functions to
- /// contained [Ok] and [Err] values.
- Result either(
- U Function(T value) valueTransformer,
- F Function(E error) errorTransformer,
- ) =>
- _either(valueTransformer, errorTransformer) as Result;
-
- /// 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,
- ) =>
- _eitherAsync(valueTransformer, errorTransformer)
- as Future>;
-
- /// Constructs a new [Result] from a function that might throw
- static Result tryCatch(
- T Function() tryFn,
- E Function(Error error) onError,
- ) {
- try {
- return Ok(tryFn());
- } on Error catch (e) {
- return Err(onError(e));
- }
- }
-
- /// Constructs a new [Result] from an **async** function that might throw
- static Future> tryCatchAsync(
- Future Function() tryFn,
- E Function(Error error) onError,
- ) async {
- try {
- return Ok(await tryFn());
- } on Error catch (e) {
- return Err(onError(e));
- }
- }
-
- /// If the condition is satify then return [value] in
- /// [Ok] else [error] in [Err]
- static Result conditional(
- bool test,
- T value,
- E error,
- ) =>
- test ? Ok(value) : Err(error);
-
- /// If the condition is satify then return *command* [value]
- /// in [Ok] else [error] in [Err]
- static Result conditionalLazy(
- bool test,
- T Function() value,
- E Function() error,
- ) =>
- test ? Ok(value()) : Err(error());
-}
-
-/// {@template ok}
-/// Contains the success value of a [Result]
-///
-/// {@macro result}
-/// {@endtemplate}
-class Ok extends Result with _Left {
- /// {@macro ok}
- const Ok(this.value) : super._();
- final T value;
-
- @override
- U _fold(U Function(T left) fnL, U Function(E right) fnR) => fnL(value);
-
- @override
- Future _foldAsync(
- Future Function(T left) fnL,
- Future Function(E right) fnR,
- ) =>
- fnL(value);
-
- @override
- Result _and(_EitherBase res) => res as Result;
-
- @override
- Result _or(_EitherBase res) => this as Result;
-
- @override
- bool _contains(U x) => value == x;
-
- @override
- T _expect(String msg) => value;
-
- @override
- E _expectErr(String msg) => throw ResultException('$msg: $value');
-
- @override
- Result _map(U Function(T value) mapper) => Ok(mapper(value));
-
- @override
- Future> _mapAsync(Future Function(T value) mapper) =>
- mapper(value).then(Ok.new);
-
- @override
- Result _mapErr(F Function(E error) mapper) => Ok(value);
-
- @override
- Future> _mapErrAsync(Future Function(E error) mapper) =>
- Future.value(Ok(value));
-
- @override
- Result _either(
- U Function(T value) fnL,
- F Function(E error) fnR,
- ) =>
- Ok(fnL(value));
-
- @override
- Future> _eitherAsync(
- Future Function(T value) fnL,
- Future Function(E error) fnR,
- ) =>
- fnL(value).then(Ok.new);
-}
-
-/// {@template err}
-/// Contains the error value of a [Result]
-///
-/// {@macro result}
-/// {@endtemplate}
-class Err extends Result with _Right {
- /// {@macro err}
- const Err(this.error) : super._();
- final E error;
-
- @override
- U _fold(U Function(T left) fnL, U Function(E right) fnR) => fnR(error);
-
- @override
- Future _foldAsync(
- Future Function(T left) fnL,
- Future Function(E right) fnR,
- ) =>
- fnR(error);
-
- @override
- Result _and(_EitherBase res) => this as Result;
- @override
- Result _or(_EitherBase res) => res as Result;
-
- @override
- bool _contains(U x) => error == x;
-
- @override
- T _expect(String msg) => throw ResultException('$msg: $error');
-
- @override
- E _expectErr(String msg) => error;
-
- @override
- Result _map(U Function(T value) mapper) => Err(error);
-
- @override
- Future> _mapAsync(Future Function(T value) mapper) =>
- Future.value(Err(error));
-
- @override
- Result _mapErr(F Function(E error) mapper) => Err(mapper(error));
-
- @override
- Future> _mapErrAsync(Future Function(E error) mapper) =>
- mapper(error).then(Err.new);
-
- @override
- Result _either(
- U Function(T value) fnL,
- F Function(E error) fnR,
- ) =>
- Err(fnR(error));
-
- @override
- Future> _eitherAsync(
- Future Function(T value) fnL,
- Future Function(E error) fnR,
- ) =>
- fnR(error).then(Err.new);
-}
diff --git a/packages/wyatt_type_utils/lib/src/extensions/iterable_extension.dart b/packages/wyatt_type_utils/lib/src/extensions/iterable_extension.dart
index 0d04c775..a0849875 100644
--- a/packages/wyatt_type_utils/lib/src/extensions/iterable_extension.dart
+++ b/packages/wyatt_type_utils/lib/src/extensions/iterable_extension.dart
@@ -37,13 +37,10 @@ extension IterableIntExtension on Iterable? {
switch (to) {
case Encoding.utf8:
str = utf8.decode(this?.toList() ?? []);
- break;
case Encoding.utf16:
str = String.fromCharCodes(this ?? []);
- break;
case Encoding.base64:
str = base64.encode(this?.toList() ?? []);
- break;
case Encoding.base16:
str = List.generate(
(this ?? []).length,
diff --git a/packages/wyatt_type_utils/lib/src/extensions/string_extension.dart b/packages/wyatt_type_utils/lib/src/extensions/string_extension.dart
index db75dd62..9510340c 100644
--- a/packages/wyatt_type_utils/lib/src/extensions/string_extension.dart
+++ b/packages/wyatt_type_utils/lib/src/extensions/string_extension.dart
@@ -33,13 +33,10 @@ extension StringExtension on String? {
switch (from) {
case Encoding.utf8:
bytes = utf8.encode(this ?? '').toTypedList();
- break;
case Encoding.utf16:
bytes = (this ?? '').runes.toList().toTypedList();
- break;
case Encoding.base64:
bytes = base64.decode(this ?? '');
- break;
case Encoding.base16:
assert(
(this ?? '').length.isEven,
diff --git a/packages/wyatt_type_utils/lib/src/pair/pair.dart b/packages/wyatt_type_utils/lib/src/pair/pair.dart
index 2a2104f9..20af8733 100644
--- a/packages/wyatt_type_utils/lib/src/pair/pair.dart
+++ b/packages/wyatt_type_utils/lib/src/pair/pair.dart
@@ -21,8 +21,10 @@ extension PairExtension on Pair {
/// {@template pair}
/// [Pair] is a simple object which contains pair of two values.
/// {@endtemplate}
+@Deprecated('Use Dart built-in record type instead')
class Pair {
/// {@macro pair}
+ @Deprecated('Use Dart built-in record type instead')
const Pair(this.left, this.right);
final L? left;
final R? right;
diff --git a/packages/wyatt_type_utils/lib/src/either/future_or_result.dart b/packages/wyatt_type_utils/lib/src/result/future_or_result.dart
similarity index 96%
rename from packages/wyatt_type_utils/lib/src/either/future_or_result.dart
rename to packages/wyatt_type_utils/lib/src/result/future_or_result.dart
index 8cf0e652..971a7f78 100644
--- a/packages/wyatt_type_utils/lib/src/either/future_or_result.dart
+++ b/packages/wyatt_type_utils/lib/src/result/future_or_result.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2024 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -14,7 +14,9 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-part of 'either_base.dart';
+import 'dart:async';
+
+import 'package:wyatt_type_utils/src/result/result.dart';
extension FutureOrResultExtension on FutureOr> {
/// Represents the left side of [Result] class.
@@ -72,13 +74,13 @@ extension FutureOrResultExtension on FutureOr> {
Future contains(U x) =>
Future.value(this).then((result) => result.contains(x));
- /// Returns the contained [Ok] value. Throw [ResultException] on [Err] with
- /// its content.
+ /// 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.
+ /// Returns the contained [Err] value. Throw [ResultException] on
+ /// [Ok] with its content.
Future expectErr(String msg) =>
Future.value(this).then((result) => result.expectErr(msg));
diff --git a/packages/wyatt_type_utils/lib/src/either/future_result.dart b/packages/wyatt_type_utils/lib/src/result/future_result.dart
similarity index 96%
rename from packages/wyatt_type_utils/lib/src/either/future_result.dart
rename to packages/wyatt_type_utils/lib/src/result/future_result.dart
index 9460b2b4..6358e70a 100644
--- a/packages/wyatt_type_utils/lib/src/either/future_result.dart
+++ b/packages/wyatt_type_utils/lib/src/result/future_result.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2024 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-part of 'either_base.dart';
+import 'package:wyatt_type_utils/src/result/result.dart';
extension FutureResultExtension on Future> {
/// Represents the left side of [Result] class.
@@ -62,12 +62,12 @@ extension FutureResultExtension on Future> {
/// the given value/error.
Future contains(U x) => then((result) => result.contains(x));
- /// Returns the contained [Ok] value. Throw [ResultException] on [Err] with
- /// its content.
+ /// Returns the contained [Ok] value. Throw [ResultException] on
+ /// [Err] with its content.
Future expect(String msg) => then((result) => result.expect(msg));
- /// Returns the contained [Err] value. Throw [ResultException] on [Ok] with
- /// its content.
+ /// Returns the contained [Err] value. Throw [ResultException] on
+ /// [Ok] with its content.
Future expectErr(String msg) => then((result) => result.expectErr(msg));
/// Maps a [Result] to [Result] by applying a function to a
diff --git a/packages/wyatt_type_utils/lib/src/result/result.dart b/packages/wyatt_type_utils/lib/src/result/result.dart
new file mode 100644
index 00000000..918562ef
--- /dev/null
+++ b/packages/wyatt_type_utils/lib/src/result/result.dart
@@ -0,0 +1,346 @@
+// Copyright (C) 2024 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 .
+
+// ignore_for_file: avoid_equals_and_hash_code_on_mutable_classes
+
+import 'package:sealed_result/sealed_result.dart' as sealed;
+
+export 'future_or_result.dart';
+export 'future_result.dart';
+
+class ResultException extends sealed.ResultException {
+ const ResultException(String super.message);
+}
+
+/// {@template result}
+/// [Result] type is coming from functional languages where exceptions are
+/// (rightfully) considered a side-effect, and therefore not appropriate to
+/// pass domain errors. Mind the difference between different kinds of errors:
+/// Some of them belong to domain, others don't.
+///
+/// *E.g. null reference exception or index out of bounds
+/// are not related to domain - they rather indicate a defect.*
+///
+/// Either is defined as a generic type with two branches
+/// - success with [Success]
+/// - failure with [Failure]
+///
+/// It can appear in two forms, where
+/// it contains an object of [Ok], or where it contains an object
+/// of [Err]. It cannot appear in both states at once, or in none of them.
+/// Therefore, if one possesses an [Result] instance, it either contains a
+/// successfully produced result, or contains an error object.
+/// {@endtemplate}
+class Result {
+ /// {@macro result}
+ const Result._(this._result);
+
+ factory Result.ok(Success value) => Ok(value);
+ factory Result.err(Failure value) => Err(value);
+ factory Result.error(Failure value) => Err(value);
+ factory Result.success(Success value) => Ok(value);
+ factory Result.failure(Failure value) => Err(value);
+
+ final sealed.Result _result;
+
+ /// Represents the left side of [Result] class.
+ bool get isOk => _result.isOk;
+
+ /// Represents the right side of [Result] class.
+ bool get isErr => _result.isErr;
+
+ /// Get nullable [Ok] value, and discarding the error, if any.
+ Success? get ok => _result.ok;
+
+ /// Get nullable [Err] value, and discarding the success value, if any.
+ Failure? get err => _result.err;
+
+ /// Get [U] value, may throw an exception.
+ U unwrap() {
+ if (U == Success) {
+ return fold(
+ (value) => value,
+ (right) => throw const ResultException(
+ 'Illegal use. You should check left value before calling',
+ ),
+ ) as U;
+ }
+ if (U == Failure) {
+ return fold(
+ (left) => throw const ResultException(
+ 'Illegal use. You should check right value before calling',
+ ),
+ (value) => value,
+ ) as U;
+ }
+ throw ResultException(
+ 'Illegal use. You should use $Success or $Failure type',
+ );
+ }
+
+ /// Get **async** [U] value, may throw an exception.
+ Future unwrapAsync() {
+ if (U == Success) {
+ return foldAsync(
+ Future.value,
+ (right) => throw const ResultException(
+ 'Illegal use. You should check left value before calling',
+ ),
+ ) as Future;
+ }
+ if (U == Failure) {
+ return foldAsync(
+ (left) => throw const ResultException(
+ 'Illegal use. You should check right value before calling',
+ ),
+ Future.value,
+ ) as Future;
+ }
+ throw ResultException(
+ 'Illegal use. You should use $Success or $Failure type',
+ );
+ }
+
+ /// Fold [Ok] and [Err] into the value of one type
+ U fold(
+ U Function(Success value) valueTransformer,
+ U Function(Failure error) errorTransformer,
+ ) =>
+ _result.fold(
+ (ok) => valueTransformer(ok),
+ (err) => errorTransformer(err),
+ );
+
+ /// Fold [Ok] and [Err] **asynchronously** into the value of one type
+ Future foldAsync(
+ Future Function(Success value) valueTransformer,
+ Future Function(Failure error) errorTransformer,
+ ) =>
+ _result.foldAsync(
+ (ok) => valueTransformer(ok),
+ (err) => errorTransformer(err),
+ );
+
+ /// Swap [Ok] and [Err]
+ Result swap() => fold(
+ Err.new,
+ Ok.new,
+ );
+
+ /// Returns [res] if the [Result] is [Ok], otherwise returns
+ /// the [Err] value of this.
+ Result and(Result res) => Result._(
+ _result.and(res._result),
+ );
+
+ /// Returns [res] if the [Result] is [Err], otherwise returns
+ /// the [Ok] value of this.
+ Result or(Result res) => Result._(
+ _result.or(res._result),
+ );
+
+ /// Returns true if the result is an [Ok] or [Err] value containing
+ /// the given value/error.
+ bool contains(U x) {
+ if (x is Success) {
+ return _result.contains(x);
+ } else if (x is Failure) {
+ return _result.containsErr(x);
+ } else {
+ throw ArgumentError('The value must be of type Success or Failure');
+ }
+ }
+
+ /// Returns the contained [Ok] value. Throw [ResultException] on [Err]
+ /// with its content.
+ Success expect(String msg) {
+ try {
+ return _result.expect(msg);
+ } on sealed.ResultException catch (e) {
+ throw ResultException(e.message.toString());
+ }
+ }
+
+ /// Returns the contained [Err] value. Throw [ResultException] on [Ok]
+ /// with its content.
+ Failure expectErr(String msg) {
+ try {
+ return _result.expectErr(msg);
+ } on sealed.ResultException catch (e) {
+ throw ResultException(e.message.toString());
+ }
+ }
+
+ /// Maps a [Result] to [Result] by applying a
+ /// function to a contained [Ok] value, leaving an [Err] value untouched.
+ Result map(U Function(Success value) mapper) =>
+ 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(Success value) mapper,
+ ) async {
+ final result = await _result.mapAsync(mapper);
+ return Result._(result);
+ }
+
+ /// Maps a [Result] to [Result] by applying a
+ /// function to a contained [Err] value, leaving an [Ok] value untouched.
+ Result mapErr(F Function(Failure error) mapper) =>
+ 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(Failure error) mapper,
+ ) async {
+ final result = await _result.mapErrAsync(mapper);
+ return Result._(result);
+ }
+
+ /// Transforms a [Result] to [Result] by applying
+ /// functions to contained [Ok] and [Err] values.
+ Result either(
+ U Function(Success value) valueTransformer,
+ F Function(Failure error) errorTransformer,
+ ) =>
+ Result._(
+ _result
+ .map(
+ valueTransformer,
+ )
+ .mapErr(
+ errorTransformer,
+ ),
+ );
+
+ /// Transforms a [Result] to [Result] by
+ /// applying **async** functions to contained [Ok] and [Err] values.
+ Future> eitherAsync(
+ Future Function(Success value) valueTransformer,
+ Future Function(Failure error) errorTransformer,
+ ) =>
+ _result
+ .mapAsync(
+ valueTransformer,
+ )
+ .mapErrAsync(
+ errorTransformer,
+ )
+ .then(Result._);
+
+ /// Constructs a new [Result] from a function that might throw
+ static Result
+ tryCatch(
+ Success Function() tryFn,
+ Failure Function(Error error) onError,
+ ) {
+ try {
+ return Ok(tryFn());
+ } on Error catch (e) {
+ return Err(onError(e));
+ }
+ }
+
+ /// Constructs a new [Result] from an **async** function that might throw
+ static Future>
+ tryCatchAsync(
+ Future Function() tryFn,
+ Failure Function(Error error) onError,
+ ) async {
+ try {
+ return Ok(await tryFn());
+ } on Error catch (e) {
+ return Err(onError(e));
+ }
+ }
+
+ /// If the condition is satify then return [value] in
+ /// [Ok] else [error] in [Err]
+ static Result conditional(
+ Success value,
+ Failure error, {
+ required bool test,
+ }) =>
+ test ? Ok(value) : Err(error);
+
+ /// If the condition is satify then return *command* [value]
+ /// in [Ok] else [error] in [Err]
+ static Result conditionalLazy(
+ Success Function() value,
+ Failure Function() error,
+ bool Function() predicate,
+ ) =>
+ predicate.call() ? Ok(value()) : Err(error());
+
+ @override
+ int get hashCode => _result.hashCode;
+
+ @override
+ bool operator ==(Object other) {
+ if (identical(this, other)) {
+ return true;
+ }
+ return other is Result && other._result == _result;
+ }
+}
+
+final class Ok extends Result {
+ Ok(this.ok) : super._(sealed.Ok(ok));
+
+ @override
+ final Success ok;
+
+ @override
+ bool get isErr => false;
+
+ @override
+ bool get isOk => true;
+
+ @override
+ Failure? get err => null;
+
+ @override
+ String toString() => switch (ok) {
+ null => 'Ok(null)',
+ Future() => 'Ok(${ok.runtimeType})',
+ _ => 'Ok($ok)',
+ };
+}
+
+final class Err extends Result {
+ Err(this.err) : super._(sealed.Err(err));
+
+ @override
+ final Failure err;
+
+ @override
+ bool get isErr => true;
+
+ @override
+ bool get isOk => false;
+
+ @override
+ Success? get ok => null;
+
+ @override
+ String toString() => switch (err) {
+ _ => 'Err($err)',
+ };
+}
diff --git a/packages/wyatt_type_utils/lib/src/src.dart b/packages/wyatt_type_utils/lib/src/src.dart
index c1d65c3c..61d12cb8 100644
--- a/packages/wyatt_type_utils/lib/src/src.dart
+++ b/packages/wyatt_type_utils/lib/src/src.dart
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 WYATT GROUP
+// Copyright (C) 2024 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@@ -17,3 +17,4 @@
export 'either/either_base.dart';
export 'extensions/extensions.dart';
export 'pair/pair.dart';
+export 'result/result.dart';
diff --git a/packages/wyatt_type_utils/pubspec.yaml b/packages/wyatt_type_utils/pubspec.yaml
index 1c818afb..57e126a1 100644
--- a/packages/wyatt_type_utils/pubspec.yaml
+++ b/packages/wyatt_type_utils/pubspec.yaml
@@ -6,11 +6,14 @@ version: 0.0.5
publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
environment:
- sdk: ">=2.17.0 <3.0.0"
+ sdk: "^3.0.0"
+
+dependencies:
+ sealed_result: ^3.0.0
dev_dependencies:
test: ^1.22.0
wyatt_analysis:
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
- version: ^2.5.0
+ version: ^2.6.1
diff --git a/packages/wyatt_type_utils/test/result_test.dart b/packages/wyatt_type_utils/test/result_test.dart
index 53706fd5..bf7be242 100644
--- a/packages/wyatt_type_utils/test/result_test.dart
+++ b/packages/wyatt_type_utils/test/result_test.dart
@@ -21,85 +21,83 @@ void main() {
group('Result', () {
test('`isOk` returns true on Ok value', () {
expect(
- const Ok(null).isOk,
+ Ok(null).isOk,
true,
);
expect(
- const Err(null).isOk,
+ Err(null).isOk,
false,
);
});
test('`isErr` returns true on Err value', () {
expect(
- const Ok(null).isErr,
+ Ok(null).isErr,
false,
);
expect(
- const Err(null).isErr,
+ Err(null).isErr,
true,
);
});
test('`ok` returns value on Ok value', () {
- const Result x = Ok(2);
+ final Result x = Ok(2);
expect(x.ok, 2);
expect(x.err, null);
});
test('`err` returns error on Err value', () {
- const Result x = Err('error');
+ final Result x = Err('error');
expect(x.ok, null);
expect(x.err, 'error');
});
test('unwrap() returns value on Ok value', () {
- const Result x = Ok(2);
+ final Result x = Ok(2);
expect(x.unwrap(), 2);
expect(() => x.unwrap(), throwsA(isException));
});
test('unwrap() returns error on Err value', () {
- const Result