Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import 'dart:async'; | 5 import 'dart:async'; |
| 6 | 6 |
| 7 import 'result/capture_transformer.dart'; | 7 import 'result/capture_transformer.dart'; |
| 8 import 'result/error.dart'; | 8 import 'result/error.dart'; |
| 9 import 'result/release_transformer.dart'; | 9 import 'result/release_transformer.dart'; |
| 10 import 'result/value.dart'; | 10 import 'result/value.dart'; |
| 11 import 'stream_sink_transformer.dart'; | 11 import 'stream_sink_transformer.dart'; |
| 12 | 12 |
| 13 /// The result of a computation. | 13 /// The result of a computation. |
| 14 /// | 14 /// |
| 15 /// Capturing a result (either a returned value or a thrown error) means | 15 /// Capturing a result (either a returned value or a thrown error) means |
| 16 /// converting it into a [Result] - either a [ValueResult] or an [ErrorResult]. | 16 /// converting it into a [Result] - either a [ValueResult] or an [ErrorResult]. |
| 17 /// | 17 /// |
| 18 /// This value can release itself by writing itself either to a [EventSink] or a | 18 /// This value can release itself by writing itself either to a [EventSink] or a |
| 19 /// [Completer], or by becoming a [Future]. | 19 /// [Completer], or by becoming a [Future]. |
| 20 /// | |
| 21 /// A [Future] represents a potential result, one that might not have been | |
| 22 /// computed yet, and a [Result] is always a completed and available result. | |
| 20 abstract class Result<T> { | 23 abstract class Result<T> { |
| 21 /// A stream transformer that captures a stream of events into [Result]s. | 24 /// A stream transformer that captures a stream of events into [Result]s. |
| 22 /// | 25 /// |
| 23 /// The result of the transformation is a stream of [Result] values and no | 26 /// The result of the transformation is a stream of [Result] values and no |
| 24 /// error events. This is the transformer used by [captureStream]. | 27 /// error events. This is the transformer used by [captureStream]. |
| 25 static const StreamTransformer<Object, Result> captureStreamTransformer = | 28 static const StreamTransformer<Object, Result> captureStreamTransformer = |
| 26 const CaptureStreamTransformer(); | 29 const CaptureStreamTransformer(); |
| 27 | 30 |
| 28 /// A stream transformer that releases a stream of result events. | 31 /// A stream transformer that releases a stream of result events. |
| 29 /// | 32 /// |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 48 const StreamSinkTransformer.fromStreamTransformer( | 51 const StreamSinkTransformer.fromStreamTransformer( |
| 49 const ReleaseStreamTransformer()); | 52 const ReleaseStreamTransformer()); |
| 50 | 53 |
| 51 /// Create a `Result` with the result of calling [computation]. | 54 /// Create a `Result` with the result of calling [computation]. |
| 52 /// | 55 /// |
| 53 /// This generates either a [ValueResult] with the value returned by | 56 /// This generates either a [ValueResult] with the value returned by |
| 54 /// calling `computation`, or an [ErrorResult] with an error thrown by | 57 /// calling `computation`, or an [ErrorResult] with an error thrown by |
| 55 /// the call. | 58 /// the call. |
| 56 factory Result(T computation()) { | 59 factory Result(T computation()) { |
| 57 try { | 60 try { |
| 58 return new ValueResult(computation()); | 61 return new ValueResult<T>(computation()); |
| 59 } catch (e, s) { | 62 } catch (e, s) { |
| 60 return new ErrorResult(e, s); | 63 return new ErrorResult(e, s); |
| 61 } | 64 } |
| 62 } | 65 } |
| 63 | 66 |
| 64 /// Create a `Result` holding a value. | 67 /// Create a `Result` holding a value. |
| 65 /// | 68 /// |
| 66 /// Alias for [ValueResult.ValueResult]. | 69 /// Alias for [ValueResult.ValueResult]. |
| 67 factory Result.value(T value) = ValueResult<T>; | 70 factory Result.value(T value) = ValueResult<T>; |
| 68 | 71 |
| 69 /// Create a `Result` holding an error. | 72 /// Create a `Result` holding an error. |
| 70 /// | 73 /// |
| 71 /// Alias for [ErrorResult.ErrorResult]. | 74 /// Alias for [ErrorResult.ErrorResult]. |
| 72 factory Result.error(Object error, [StackTrace stackTrace]) => | 75 factory Result.error(Object error, [StackTrace stackTrace]) => |
| 73 new ErrorResult(error, stackTrace); | 76 new ErrorResult(error, stackTrace); |
| 74 | 77 |
| 75 /// Capture the result of a future into a `Result` future. | 78 /// Capture the result of a future into a `Result` future. |
| 76 /// | 79 /// |
| 77 /// The resulting future will never have an error. | 80 /// The resulting future will never have an error. |
| 78 /// Errors have been converted to an [ErrorResult] value. | 81 /// Errors have been converted to an [ErrorResult] value. |
| 79 static Future<Result<T>> capture<T>(Future<T> future) { | 82 static Future<Result<T>> capture<T>(Future<T> future) { |
| 80 return future.then((value) => new ValueResult(value), | 83 return future.then((value) => new ValueResult(value), |
| 81 onError: (error, stackTrace) => new ErrorResult<T>(error, stackTrace)); | 84 onError: (error, stackTrace) => new ErrorResult<T>(error, stackTrace)); |
| 82 } | 85 } |
| 83 | 86 |
| 87 /// Capture each future in [elements], | |
|
floitsch
2017/08/17 15:29:22
Dartdoc wants third person. Here and for all other
| |
| 88 /// | |
| 89 /// Returns a (future of) a list of results for each element in [elements], | |
| 90 /// in iteration order. | |
| 91 /// Each future in [elements] is [capture]d and each non-future is | |
| 92 /// wrapped as a [Result.value]. | |
| 93 /// The returned future will never have an error. | |
| 94 static Future<List<Result<T>>> captureAll<T>(Iterable<FutureOr<T>> elements) { | |
| 95 var results = <T>[]; | |
| 96 int pending = 0; | |
| 97 var completer; | |
| 98 for (var element in elements) { | |
| 99 if (element is Future<T>) { | |
| 100 int i = results.length; | |
| 101 results.add(null); | |
| 102 pending++; | |
| 103 Result.capture<T>(element).then((result) { | |
| 104 results[i] = result; | |
| 105 if (--pending == 0) { | |
| 106 completer.complete(results); | |
| 107 } | |
| 108 }); | |
| 109 } else { | |
| 110 results.add(new Result<T>.value(element)); | |
| 111 } | |
| 112 } | |
| 113 if (pending == 0) { | |
| 114 return new Future<List<Result<T>>>.value(results); | |
| 115 } | |
| 116 completer = Completer<List<Result<T>>>(); | |
| 117 return completer.future; | |
| 118 } | |
| 119 | |
| 84 /// Release the result of a captured future. | 120 /// Release the result of a captured future. |
| 85 /// | 121 /// |
| 86 /// Converts the [Result] value of the given [future] to a value or error | 122 /// Converts the [Result] value of the given [future] to a value or error |
| 87 /// completion of the returned future. | 123 /// completion of the returned future. |
| 88 /// | 124 /// |
| 89 /// If [future] completes with an error, the returned future completes with | 125 /// If [future] completes with an error, the returned future completes with |
| 90 /// the same error. | 126 /// the same error. |
| 91 static Future<T> release<T>(Future<Result<T>> future) => | 127 static Future<T> release<T>(Future<Result<T>> future) => |
| 92 future.then<T>((result) => result.asFuture); | 128 future.then<T>((result) => result.asFuture); |
| 93 | 129 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 107 source.transform(new ReleaseStreamTransformer<T>()); | 143 source.transform(new ReleaseStreamTransformer<T>()); |
| 108 | 144 |
| 109 /// Converts a result of a result to a single result. | 145 /// Converts a result of a result to a single result. |
| 110 /// | 146 /// |
| 111 /// If the result is an error, or it is a `Result` value | 147 /// If the result is an error, or it is a `Result` value |
| 112 /// which is then an error, then a result with that error is returned. | 148 /// which is then an error, then a result with that error is returned. |
| 113 /// Otherwise both levels of results are value results, and a single | 149 /// Otherwise both levels of results are value results, and a single |
| 114 /// result with the value is returned. | 150 /// result with the value is returned. |
| 115 static Result<T> flatten<T>(Result<Result<T>> result) { | 151 static Result<T> flatten<T>(Result<Result<T>> result) { |
| 116 if (result.isValue) return result.asValue.value; | 152 if (result.isValue) return result.asValue.value; |
| 117 return new ErrorResult<T>(result.asError.error, result.asError.stackTrace); | 153 return result.asError; |
| 154 } | |
| 155 | |
| 156 /// Converts a sequence of results to a result of a list. | |
| 157 /// | |
| 158 /// Returns either a list of values if [results] doesn't contain any errors, | |
| 159 /// or the first error result in [results]. | |
| 160 static Result<List<T>> flattenList(Iterable<Result<T>> results) { | |
| 161 var values = <T>[]; | |
| 162 for (var result in results) { | |
| 163 if (result.isValue) { | |
| 164 values.add(result.asValue.value); | |
| 165 } | |
| 166 return result.asError; | |
| 167 } | |
| 168 return new Result<List<T>>.value(values); | |
| 118 } | 169 } |
| 119 | 170 |
| 120 /// Whether this result is a value result. | 171 /// Whether this result is a value result. |
| 121 /// | 172 /// |
| 122 /// Always the opposite of [isError]. | 173 /// Always the opposite of [isError]. |
| 123 bool get isValue; | 174 bool get isValue; |
| 124 | 175 |
| 125 /// Whether this result is an error result. | 176 /// Whether this result is an error result. |
| 126 /// | 177 /// |
| 127 /// Always the opposite of [isValue]. | 178 /// Always the opposite of [isValue]. |
| 128 bool get isError; | 179 bool get isError; |
| 129 | 180 |
| 130 /// If this is a value result, return itself. | 181 /// If this is a value result, return itself. |
| 131 /// | 182 /// |
| 132 /// Otherwise return `null`. | 183 /// Otherwise return `null`. |
| 133 ValueResult<T> get asValue; | 184 ValueResult<T> get asValue; |
| 134 | 185 |
| 135 /// If this is an error result, return itself. | 186 /// If this is an error result, return itself. |
| 136 /// | 187 /// |
| 137 /// Otherwise return `null`. | 188 /// Otherwise return `null`. |
| 138 ErrorResult<T> get asError; | 189 ErrorResult get asError; |
| 139 | 190 |
| 140 /// Complete a completer with this result. | 191 /// Complete a completer with this result. |
| 141 void complete(Completer<T> completer); | 192 void complete(Completer<T> completer); |
| 142 | 193 |
| 143 /// Add this result to an [EventSink]. | 194 /// Add this result to an [EventSink]. |
| 144 /// | 195 /// |
| 145 /// Calls the sink's `add` or `addError` method as appropriate. | 196 /// Calls the sink's `add` or `addError` method as appropriate. |
| 146 void addTo(EventSink<T> sink); | 197 void addTo(EventSink<T> sink); |
| 147 | 198 |
| 148 /// Creates a future completed with this result as a value or an error. | 199 /// A future that has been completed with this result as a value or an error. |
| 149 Future<T> get asFuture; | 200 Future<T> get asFuture; |
| 150 } | 201 } |
| OLD | NEW |