Add `value` getter to `Result` (#969)
This is the synchronous version of `asFuture`. Typical uses of `Result`
are asynchronous and the `asFuture` API is sufficient.
The `ValueResult` has a `result` member already, graduating this to the
`Result` super class allows callers to use it without checking the type
first.
diff --git a/pkgs/async/CHANGELOG.md b/pkgs/async/CHANGELOG.md
index 48a3b44..a45dc81 100644
--- a/pkgs/async/CHANGELOG.md
+++ b/pkgs/async/CHANGELOG.md
@@ -4,6 +4,7 @@
with variable intervals.
- Mark `Result` as `sealed`, and `ValueResult`, and `ErrorResult` as `final`
classes.
+- Add `value` getter to `Result`.
## 2.13.1
diff --git a/pkgs/async/lib/src/result/error.dart b/pkgs/async/lib/src/result/error.dart
index f17ab07..fcf3ec8 100644
--- a/pkgs/async/lib/src/result/error.dart
+++ b/pkgs/async/lib/src/result/error.dart
@@ -37,6 +37,11 @@
@override
Future<Never> get asFuture => Future<Never>.error(error, stackTrace);
+ @override
+ Never get value {
+ Error.throwWithStackTrace(error, stackTrace);
+ }
+
/// Calls an error handler with the error and stacktrace.
///
/// An async error handler function is either a function expecting two
diff --git a/pkgs/async/lib/src/result/result.dart b/pkgs/async/lib/src/result/result.dart
index ba43642..8407cd3 100644
--- a/pkgs/async/lib/src/result/result.dart
+++ b/pkgs/async/lib/src/result/result.dart
@@ -221,6 +221,16 @@
/// Calls the sink's `add` or `addError` method as appropriate.
void addTo(EventSink<T> sink);
+ /// The value of this result, or throws the error if this is an error result.
+ ///
+ /// If this is a [ValueResult], returns its value.
+ /// If this is an [ErrorResult], throws its error with its stack trace
+ /// using [Error.throwWithStackTrace].
+ ///
+ /// To read the value without the risk of an exception first check [isValue]
+ /// or use [asValue] to get `null` instead.
+ T get value;
+
/// A future that has been completed with this result as a value or an error.
Future<T> get asFuture;
}
diff --git a/pkgs/async/lib/src/result/value.dart b/pkgs/async/lib/src/result/value.dart
index 8b5bb10..8eb42cb 100644
--- a/pkgs/async/lib/src/result/value.dart
+++ b/pkgs/async/lib/src/result/value.dart
@@ -7,6 +7,7 @@
/// A result representing a returned value.
final class ValueResult<T> implements Result<T> {
/// The result of a successful computation.
+ @override
final T value;
@override
diff --git a/pkgs/async/test/result/result_test.dart b/pkgs/async/test/result/result_test.dart
index 65d47f9..066f2e3 100644
--- a/pkgs/async/test/result/result_test.dart
+++ b/pkgs/async/test/result/result_test.dart
@@ -131,6 +131,30 @@
);
});
+ group('value', () {
+ test('returns value for ValueResult', () {
+ var result = Result<int>.value(42);
+ expect(result.value, equals(42));
+ });
+
+ test('throws error for ErrorResult', () {
+ var result = Result<int>.error('BAD', stack);
+ expect(() => result.value, throwsA('BAD'));
+ });
+
+ test('throws error with stack trace for ErrorResult', () {
+ var result = Result<int>.error('BAD', stack);
+ // Use try/catch over throwsA to check expectations about the stack trace
+ try {
+ result.value;
+ fail('Expected error to be thrown');
+ } catch (e, s) {
+ expect(e, equals('BAD'));
+ expect(Trace.from(s).toString(), equals(stack.toString()));
+ }
+ });
+ });
+
test('capture future value', () {
var value = Future<int>.value(42);
Result.capture(value).then(