Chromium Code Reviews| Index: lib/src/result.dart |
| diff --git a/lib/src/result.dart b/lib/src/result.dart |
| index 49457c35fa113edd7d2ecc629ea5e360b14e9ab4..a4112a9a69a0a8cbe6c484b2cddc7643fe6884ee 100644 |
| --- a/lib/src/result.dart |
| +++ b/lib/src/result.dart |
| @@ -17,6 +17,9 @@ import 'stream_sink_transformer.dart'; |
| /// |
| /// This value can release itself by writing itself either to a [EventSink] or a |
| /// [Completer], or by becoming a [Future]. |
| +/// |
| +/// A [Future] represents a potential result, one that might not have been |
| +/// computed yet, and a [Result] is always a completed and available result. |
| abstract class Result<T> { |
| /// A stream transformer that captures a stream of events into [Result]s. |
| /// |
| @@ -55,7 +58,7 @@ abstract class Result<T> { |
| /// the call. |
| factory Result(T computation()) { |
| try { |
| - return new ValueResult(computation()); |
| + return new ValueResult<T>(computation()); |
| } catch (e, s) { |
| return new ErrorResult(e, s); |
| } |
| @@ -81,6 +84,39 @@ abstract class Result<T> { |
| onError: (error, stackTrace) => new ErrorResult<T>(error, stackTrace)); |
| } |
| + /// Capture each future in [elements], |
|
floitsch
2017/08/17 15:29:22
Dartdoc wants third person. Here and for all other
|
| + /// |
| + /// Returns a (future of) a list of results for each element in [elements], |
| + /// in iteration order. |
| + /// Each future in [elements] is [capture]d and each non-future is |
| + /// wrapped as a [Result.value]. |
| + /// The returned future will never have an error. |
| + static Future<List<Result<T>>> captureAll<T>(Iterable<FutureOr<T>> elements) { |
| + var results = <T>[]; |
| + int pending = 0; |
| + var completer; |
| + for (var element in elements) { |
| + if (element is Future<T>) { |
| + int i = results.length; |
| + results.add(null); |
| + pending++; |
| + Result.capture<T>(element).then((result) { |
| + results[i] = result; |
| + if (--pending == 0) { |
| + completer.complete(results); |
| + } |
| + }); |
| + } else { |
| + results.add(new Result<T>.value(element)); |
| + } |
| + } |
| + if (pending == 0) { |
| + return new Future<List<Result<T>>>.value(results); |
| + } |
| + completer = Completer<List<Result<T>>>(); |
| + return completer.future; |
| + } |
| + |
| /// Release the result of a captured future. |
| /// |
| /// Converts the [Result] value of the given [future] to a value or error |
| @@ -114,7 +150,22 @@ abstract class Result<T> { |
| /// result with the value is returned. |
| static Result<T> flatten<T>(Result<Result<T>> result) { |
| if (result.isValue) return result.asValue.value; |
| - return new ErrorResult<T>(result.asError.error, result.asError.stackTrace); |
| + return result.asError; |
| + } |
| + |
| + /// Converts a sequence of results to a result of a list. |
| + /// |
| + /// Returns either a list of values if [results] doesn't contain any errors, |
| + /// or the first error result in [results]. |
| + static Result<List<T>> flattenList(Iterable<Result<T>> results) { |
| + var values = <T>[]; |
| + for (var result in results) { |
| + if (result.isValue) { |
| + values.add(result.asValue.value); |
| + } |
| + return result.asError; |
| + } |
| + return new Result<List<T>>.value(values); |
| } |
| /// Whether this result is a value result. |
| @@ -135,7 +186,7 @@ abstract class Result<T> { |
| /// If this is an error result, return itself. |
| /// |
| /// Otherwise return `null`. |
| - ErrorResult<T> get asError; |
| + ErrorResult get asError; |
| /// Complete a completer with this result. |
| void complete(Completer<T> completer); |
| @@ -145,6 +196,6 @@ abstract class Result<T> { |
| /// Calls the sink's `add` or `addError` method as appropriate. |
| void addTo(EventSink<T> sink); |
| - /// Creates a future completed with this result as a value or an error. |
| + /// A future that has been completed with this result as a value or an error. |
| Future<T> get asFuture; |
| } |