Modernize the package's style.
This moves the package to new-style doc comments, deprecates separate
top-level libraries, and removes library tags. It also deprecates some
top-level classes in favor of static const fields.
There's more that could be done, but this fixes most of the low-hanging
fruit.
R=lrn@google.com
Review URL: https://codereview.chromium.org//1777453002 .
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 15570d7..946d3a8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,16 @@
+## 1.9.0
+
+* Deprecate top-level libraries other than `package:async/async.dart`, which
+ exports these libraries' interfaces.
+
+* Add `Result.captureStreamTransformer`, `Result.releaseStreamTransformer`,
+ `Result.captureSinkTransformer`, and `Result.releaseSinkTransformer`.
+
+* Deprecate `CaptureStreamTransformer`, `ReleaseStreamTransformer`,
+ `CaptureSink`, and `ReleaseSink`. `Result.captureStreamTransformer`,
+ `Result.releaseStreamTransformer`, `Result.captureSinkTransformer`, and
+ `Result.releaseSinkTransformer` should be used instead.
+
## 1.8.0
- Added `StreamSinkCompleter`, for creating a `StreamSink` now and providing its
diff --git a/README.md b/README.md
index 3820f06..16cd55f 100644
--- a/README.md
+++ b/README.md
@@ -1,28 +1,15 @@
-# Async utilities package
-
-Contains tools to work with asynchronous computations.
-
-The package contains `Stream` and `Future` related functionality,
-as well as sub-libraries with different utilities.
+Contains utility classes in the style of `dart:async` to work with asynchronous
+computations.
### Zipping streams
-The "stream_zip.dart" sub-library contains functionality
-to combine several streams of events into a single stream of tuples of events.
+The `StreamZip` class can combine several streams of events into a single stream
+of tuples of events.
### Results
-The "result.dart" sub-library introduces a `Result` class that can hold either
-a value or an error.
-It allows capturing an asynchronous computation which can give either a value
-or an error, into an asynchronous computation that always gives a `Result`
-value, where errors can be treated as data.
-It also allows releasing the `Result` back into an asynchronous computation.
-### History.
-This package is unrelated to the discontinued `async` package with version 0.1.7.
-
-## Features and bugs
-
-Please file feature requests and bugs at the [issue tracker][tracker].
-
-[tracker]: https://github.com/dart-lang/async/issues
+The package introduces a `Result` class that can hold either a value or an
+error. It allows capturing an asynchronous computation which can give either a
+value or an error, into an asynchronous computation that always gives a `Result`
+value, where errors can be treated as data. It also allows releasing the
+`Result` back into an asynchronous computation.
diff --git a/lib/async.dart b/lib/async.dart
index ef1ac04..0d3e051 100644
--- a/lib/async.dart
+++ b/lib/async.dart
@@ -2,9 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library dart.pkg.async;
-
-export "result.dart";
export "src/async_memoizer.dart";
export "src/cancelable_operation.dart";
export "src/delegate/event_sink.dart";
@@ -17,7 +14,12 @@
export "src/lazy_stream.dart";
export "src/null_stream_sink.dart";
export "src/restartable_timer.dart";
-export "src/result_future.dart";
+export "src/result.dart";
+export "src/result/capture_transformer.dart";
+export "src/result/error.dart";
+export "src/result/future.dart";
+export "src/result/release_transformer.dart";
+export "src/result/value.dart";
export "src/single_subscription_transformer.dart";
export "src/stream_completer.dart";
export "src/stream_group.dart";
@@ -25,5 +27,5 @@
export "src/stream_sink_completer.dart";
export "src/stream_sink_transformer.dart";
export "src/stream_splitter.dart";
+export "src/stream_zip.dart";
export "src/subscription_stream.dart";
-export "stream_zip.dart";
diff --git a/lib/result.dart b/lib/result.dart
index 13e3dd9..627f200 100644
--- a/lib/result.dart
+++ b/lib/result.dart
@@ -2,255 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/// Capture asynchronous results into synchronous values.
-///
-/// Capturing a result (either a returned value or a thrown error)
-/// means converting it into a [Result] -
-/// either a [ValueResult] or an [ErrorResult].
-///
-/// This value can release itself by writing itself either to a
-/// [EventSink] or a [Completer], or by becoming a [Future].
+/// Import `async.dart` instead.
+@Deprecated("Will be removed in async 2.0.0.")
library dart.pkg.async.results;
-import "dart:async";
-
-/// The result of a computation.
-abstract class Result<T> {
- /// Create a `Result` with the result of calling [computation].
- ///
- /// This generates either a [ValueResult] with the value returned by
- /// calling `computation`, or an [ErrorResult] with an error thrown by
- /// the call.
- factory Result(T computation()) {
- try {
- return new ValueResult(computation());
- } catch (e, s) {
- return new ErrorResult(e, s);
- }
- }
-
- /// Create a `Result` holding a value.
- ///
- /// Alias for [ValueResult.ValueResult].
- factory Result.value(T value) = ValueResult<T>;
-
- /// Create a `Result` holding an error.
- ///
- /// Alias for [ErrorResult.ErrorResult].
- factory Result.error(Object error, [StackTrace stackTrace]) =>
- new ErrorResult(error, stackTrace);
-
- // Helper functions.
- static _captureValue(value) => new ValueResult(value);
- static _captureError(error, stack) => new ErrorResult(error, stack);
- static _release(Result v) {
- if (v.isValue) return v.asValue.value; // Avoid wrapping in future.
- return v.asFuture;
- }
-
- /// Capture the result of a future into a `Result` future.
- ///
- /// The resulting future will never have an error.
- /// Errors have been converted to an [ErrorResult] value.
- static Future<Result> capture(Future future) {
- return future.then(_captureValue, onError: _captureError);
- }
-
- /// Release the result of a captured future.
- ///
- /// Converts the [Result] value of the given [future] to a value or error
- /// completion of the returned future.
- ///
- /// If [future] completes with an error, the returned future completes with
- /// the same error.
- static Future release(Future<Result> future) {
- return future.then(_release);
- }
-
- /// Capture the results of a stream into a stream of [Result] values.
- ///
- /// The returned stream will not have any error events.
- /// Errors from the source stream have been converted to [ErrorResult]s.
- ///
- /// Shorthand for transforming the stream using [CaptureStreamTransformer].
- static Stream<Result> captureStream(Stream source) {
- return source.transform(const CaptureStreamTransformer());
- }
-
- /// Release a stream of [result] values into a stream of the results.
- ///
- /// `Result` values of the source stream become value or error events in
- /// the returned stream as appropriate.
- /// Errors from the source stream become errors in the returned stream.
- ///
- /// Shorthand for transforming the stream using [ReleaseStreamTransformer].
- static Stream releaseStream(Stream<Result> source) {
- return source.transform(const ReleaseStreamTransformer());
- }
-
- /// Converts a result of a result to a single result.
- ///
- /// If the result is an error, or it is a `Result` value
- /// which is then an error, then a result with that error is returned.
- /// Otherwise both levels of results are value results, and a single
- /// result with the value is returned.
- static Result flatten(Result<Result> result) {
- if (result.isError) return result;
- return result.asValue.value;
- }
-
- /// Whether this result is a value result.
- ///
- /// Always the opposite of [isError].
- bool get isValue;
-
- /// Whether this result is an error result.
- ///
- /// Always the opposite of [isValue].
- bool get isError;
-
- /// If this is a value result, return itself.
- ///
- /// Otherwise return `null`.
- ValueResult<T> get asValue;
-
- /// If this is an error result, return itself.
- ///
- /// Otherwise return `null`.
- ErrorResult get asError;
-
- /// Complete a completer with this result.
- void complete(Completer<T> completer);
-
- /// Add this result to an [EventSink].
- ///
- /// 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.
- Future<T> get asFuture;
-}
-
-/// A result representing a returned value.
-class ValueResult<T> implements Result<T> {
- final T value;
- ValueResult(this.value);
- bool get isValue => true;
- bool get isError => false;
- ValueResult<T> get asValue => this;
- ErrorResult get asError => null;
- void complete(Completer<T> completer) {
- completer.complete(value);
- }
- void addTo(EventSink<T> sink) {
- sink.add(value);
- }
- Future<T> get asFuture => new Future.value(value);
-}
-
-/// A result representing a thrown error.
-class ErrorResult implements Result {
- final error;
- final StackTrace stackTrace;
- ErrorResult(this.error, this.stackTrace);
- bool get isValue => false;
- bool get isError => true;
- ValueResult get asValue => null;
- ErrorResult get asError => this;
- void complete(Completer completer) {
- completer.completeError(error, stackTrace);
- }
- void addTo(EventSink sink) {
- sink.addError(error, stackTrace);
- }
- Future get asFuture => new Future.error(error, stackTrace);
-
- /// Calls an error handler with the error and stacktrace.
- ///
- /// An async error handler function is either a function expecting two
- /// arguments, which will be called with the error and the stack trace,
- /// or it has to be a function expecting only one argument,
- /// which will be called with only the error.
- void handle(Function errorHandler) {
- if (errorHandler is ZoneBinaryCallback) {
- errorHandler(error, stackTrace);
- } else {
- errorHandler(error);
- }
- }
-}
-
-/// A stream transformer that captures a stream of events into [Result]s.
-///
-/// The result of the transformation is a stream of [Result] values and
-/// no error events.
-class CaptureStreamTransformer<T> implements StreamTransformer<T, Result<T>> {
- const CaptureStreamTransformer();
-
- Stream<Result<T>> bind(Stream<T> source) {
- return new Stream<Result<T>>.eventTransformed(source, _createSink);
- }
-
- static EventSink _createSink(EventSink<Result> sink) {
- return new CaptureSink(sink);
- }
-}
-
-/// A stream transformer that releases a stream of result events.
-///
-/// The result of the transformation is a stream of values and
-/// error events.
-class ReleaseStreamTransformer<T> implements StreamTransformer<Result<T>, T> {
- const ReleaseStreamTransformer();
-
- Stream<T> bind(Stream<Result<T>> source) {
- return new Stream<T>.eventTransformed(source, _createSink);
- }
-
- static EventSink<Result> _createSink(EventSink sink) {
- return new ReleaseSink(sink);
- }
-}
-
-/// An event sink wrapper that captures the incoming events.
-///
-/// Wraps an [EventSink] that expects [Result] values.
-/// Accepts any value and error result,
-/// and passes them to the wrapped sink as [Result] values.
-///
-/// The wrapped sink will never receive an error event.
-class CaptureSink<T> implements EventSink<T> {
- final EventSink _sink;
-
- CaptureSink(EventSink<Result<T>> sink) : _sink = sink;
- void add(T value) { _sink.add(new ValueResult(value)); }
- void addError(Object error, [StackTrace stackTrace]) {
- _sink.add(new ErrorResult(error, stackTrace));
- }
- void close() { _sink.close(); }
-}
-
-/// An event sink wrapper that releases the incoming result events.
-///
-/// Wraps an output [EventSink] that expects any result.
-/// Accepts [Result] values, and puts the result value or error into the
-/// corresponding output sink add method.
-class ReleaseSink<T> implements EventSink<Result<T>> {
- final EventSink _sink;
- ReleaseSink(EventSink<T> sink) : _sink = sink;
- void add(Result<T> result) {
- if (result.isValue) {
- _sink.add(result.asValue.value);
- } else {
- ErrorResult error = result.asError;
- _sink.addError(error.error, error.stackTrace);
- }
- }
- void addError(Object error, [StackTrace stackTrace]) {
- // Errors may be added by intermediate processing, even if it is never
- // added by CaptureSink.
- _sink.addError(error, stackTrace);
- }
-
- void close() { _sink.close(); }
-}
+export "src/result.dart";
+export "src/result/capture_transformer.dart";
+export "src/result/error.dart";
+export "src/result/release_transformer.dart";
+export "src/result/value.dart";
diff --git a/lib/src/async_memoizer.dart b/lib/src/async_memoizer.dart
index 41c3dae..3612a7d 100644
--- a/lib/src/async_memoizer.dart
+++ b/lib/src/async_memoizer.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.async_memoizer;
-
import 'dart:async';
/// A class for running an asynchronous function exactly once and caching its
@@ -35,12 +33,12 @@
Future<T> get future => _completer.future;
final _completer = new Completer();
- /// Whether [run] has been called yet.
+ /// Whether [runOnce] has been called yet.
bool get hasRun => _completer.isCompleted;
/// Runs the function, [computation], if it hasn't been run before.
///
- /// If [run] has already been called, this returns the original result.
+ /// If [runOnce] has already been called, this returns the original result.
Future<T> runOnce(computation()) {
if (!hasRun) _completer.complete(new Future.sync(computation));
return future;
diff --git a/lib/src/cancelable_operation.dart b/lib/src/cancelable_operation.dart
index a48c94f..1ba6b3c 100644
--- a/lib/src/cancelable_operation.dart
+++ b/lib/src/cancelable_operation.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.cancelable_operation;
-
import 'dart:async';
import 'package:async/async.dart';
diff --git a/lib/src/delegate/event_sink.dart b/lib/src/delegate/event_sink.dart
index 337e7a8..5a525df 100644
--- a/lib/src/delegate/event_sink.dart
+++ b/lib/src/delegate/event_sink.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.delegate.event_sink;
-
import 'dart:async';
/// Simple delegating wrapper around an [EventSink].
diff --git a/lib/src/delegate/future.dart b/lib/src/delegate/future.dart
index 34f6158..5e84e4f 100644
--- a/lib/src/delegate/future.dart
+++ b/lib/src/delegate/future.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.delegate.future;
-
import 'dart:async';
/// A wrapper that forwards calls to a [Future].
diff --git a/lib/src/delegate/sink.dart b/lib/src/delegate/sink.dart
index bb50da3..cee2937 100644
--- a/lib/src/delegate/sink.dart
+++ b/lib/src/delegate/sink.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.delegate.sink;
-
/// Simple delegating wrapper around a [Sink].
///
/// Subclasses can override individual methods, or use this to expose only the
diff --git a/lib/src/delegate/stream_consumer.dart b/lib/src/delegate/stream_consumer.dart
index 8162db6..dcaf0c2 100644
--- a/lib/src/delegate/stream_consumer.dart
+++ b/lib/src/delegate/stream_consumer.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.delegate.stream_consumer;
-
import 'dart:async';
/// Simple delegating wrapper around a [StreamConsumer].
diff --git a/lib/src/delegate/stream_sink.dart b/lib/src/delegate/stream_sink.dart
index b6ace65..e06afc1 100644
--- a/lib/src/delegate/stream_sink.dart
+++ b/lib/src/delegate/stream_sink.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.delegate.stream_sink;
-
import 'dart:async';
/// Simple delegating wrapper around a [StreamSink].
diff --git a/lib/src/delegate/stream_subscription.dart b/lib/src/delegate/stream_subscription.dart
index ff9b665..e7153b2 100644
--- a/lib/src/delegate/stream_subscription.dart
+++ b/lib/src/delegate/stream_subscription.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.delegate.stream_subscription;
-
import 'dart:async';
/// Simple delegating wrapper around a [StreamSubscription].
diff --git a/lib/src/future_group.dart b/lib/src/future_group.dart
index 02ff185..114c133 100644
--- a/lib/src/future_group.dart
+++ b/lib/src/future_group.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.future_group;
-
import 'dart:async';
/// A collection of futures waits until all added [Future]s complete.
@@ -35,7 +33,7 @@
Future<List<T>> get future => _completer.future;
final _completer = new Completer<List<T>>();
- /// Whether this group is waiting on any futures.
+ /// Whether this group has no pending futures.
bool get isIdle => _pending == 0;
/// A broadcast stream that emits a `null` event whenever the last pending
diff --git a/lib/src/lazy_stream.dart b/lib/src/lazy_stream.dart
index 1878d4c..3ba4953 100644
--- a/lib/src/lazy_stream.dart
+++ b/lib/src/lazy_stream.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.lazy_stream;
-
import "dart:async";
import "stream_completer.dart";
diff --git a/lib/src/null_stream_sink.dart b/lib/src/null_stream_sink.dart
index aa85924..c83790c 100644
--- a/lib/src/null_stream_sink.dart
+++ b/lib/src/null_stream_sink.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.null_stream_sink;
-
import 'dart:async';
/// A [StreamSink] that discards all events.
diff --git a/lib/src/restartable_timer.dart b/lib/src/restartable_timer.dart
index 05196d2..eed51e6 100644
--- a/lib/src/restartable_timer.dart
+++ b/lib/src/restartable_timer.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.restartable_timer;
-
import 'dart:async';
/// A non-periodic timer that can be restarted any number of times.
diff --git a/lib/src/result.dart b/lib/src/result.dart
new file mode 100644
index 0000000..482cf9b
--- /dev/null
+++ b/lib/src/result.dart
@@ -0,0 +1,164 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'result/capture_transformer.dart';
+import 'result/error.dart';
+import 'result/release_transformer.dart';
+import 'result/value.dart';
+import 'stream_sink_transformer.dart';
+
+/// The result of a computation.
+///
+/// Capturing a result (either a returned value or a thrown error) means
+/// converting it into a [Result] - either a [ValueResult] or an [ErrorResult].
+///
+/// This value can release itself by writing itself either to a [EventSink] or a
+/// [Completer], or by becoming a [Future].
+abstract class Result<T> {
+ /// A stream transformer that captures a stream of events into [Result]s.
+ ///
+ /// The result of the transformation is a stream of [Result] values and no
+ /// error events. This is the transformer used by [captureStream].
+ static const StreamTransformer<Object, Result> captureStreamTransformer =
+ const CaptureStreamTransformer();
+
+ /// A stream transformer that releases a stream of result events.
+ ///
+ /// The result of the transformation is a stream of values and error events.
+ /// This is the transformer used by [releaseStream].
+ static const StreamTransformer<Object, Result> releaseStreamTransformer =
+ const ReleaseStreamTransformer();
+
+ /// A sink transformer that captures events into [Result]s.
+ ///
+ /// The result of the transformation is a sink that only forwards [Result]
+ /// values and no error events.
+ static const StreamSinkTransformer<Object, Result> captureSinkTransformer =
+ const StreamSinkTransformer.fromStreamTransformer(
+ const CaptureStreamTransformer());
+
+ /// A sink transformer that releases result events.
+ ///
+ /// The result of the transformation is a sink that forwards of values and
+ /// error events.
+ static const StreamSinkTransformer<Object, Result> releaseSinkTransformer =
+ const StreamSinkTransformer.fromStreamTransformer(
+ const ReleaseStreamTransformer());
+
+ /// Create a `Result` with the result of calling [computation].
+ ///
+ /// This generates either a [ValueResult] with the value returned by
+ /// calling `computation`, or an [ErrorResult] with an error thrown by
+ /// the call.
+ factory Result(T computation()) {
+ try {
+ return new ValueResult(computation());
+ } catch (e, s) {
+ return new ErrorResult(e, s);
+ }
+ }
+
+ /// Create a `Result` holding a value.
+ ///
+ /// Alias for [ValueResult.ValueResult].
+ factory Result.value(T value) = ValueResult<T>;
+
+ /// Create a `Result` holding an error.
+ ///
+ /// Alias for [ErrorResult.ErrorResult].
+ factory Result.error(Object error, [StackTrace stackTrace]) =>
+ new ErrorResult(error, stackTrace);
+
+ // Helper functions.
+ static _captureValue(value) => new ValueResult(value);
+ static _captureError(error, stack) => new ErrorResult(error, stack);
+ static _release(Result v) {
+ if (v.isValue) return v.asValue.value; // Avoid wrapping in future.
+ return v.asFuture;
+ }
+
+ /// Capture the result of a future into a `Result` future.
+ ///
+ /// The resulting future will never have an error.
+ /// Errors have been converted to an [ErrorResult] value.
+ static Future<Result> capture(Future future) {
+ return future.then(_captureValue, onError: _captureError);
+ }
+
+ /// Release the result of a captured future.
+ ///
+ /// Converts the [Result] value of the given [future] to a value or error
+ /// completion of the returned future.
+ ///
+ /// If [future] completes with an error, the returned future completes with
+ /// the same error.
+ static Future release(Future<Result> future) {
+ return future.then(_release);
+ }
+
+ /// Capture the results of a stream into a stream of [Result] values.
+ ///
+ /// The returned stream will not have any error events.
+ /// Errors from the source stream have been converted to [ErrorResult]s.
+ ///
+ /// Shorthand for transforming the stream using [captureStreamTransformer].
+ static Stream<Result> captureStream(Stream source) {
+ return source.transform(captureStreamTransformer);
+ }
+
+ /// Release a stream of [result] values into a stream of the results.
+ ///
+ /// `Result` values of the source stream become value or error events in
+ /// the returned stream as appropriate.
+ /// Errors from the source stream become errors in the returned stream.
+ ///
+ /// Shorthand for transforming the stream using [releaseStreamTransformer].
+ static Stream releaseStream(Stream<Result> source) {
+ return source.transform(releaseStreamTransformer);
+ }
+
+ /// Converts a result of a result to a single result.
+ ///
+ /// If the result is an error, or it is a `Result` value
+ /// which is then an error, then a result with that error is returned.
+ /// Otherwise both levels of results are value results, and a single
+ /// result with the value is returned.
+ static Result flatten(Result<Result> result) {
+ if (result.isError) return result;
+ return result.asValue.value;
+ }
+
+ /// Whether this result is a value result.
+ ///
+ /// Always the opposite of [isError].
+ bool get isValue;
+
+ /// Whether this result is an error result.
+ ///
+ /// Always the opposite of [isValue].
+ bool get isError;
+
+ /// If this is a value result, return itself.
+ ///
+ /// Otherwise return `null`.
+ ValueResult<T> get asValue;
+
+ /// If this is an error result, return itself.
+ ///
+ /// Otherwise return `null`.
+ ErrorResult get asError;
+
+ /// Complete a completer with this result.
+ void complete(Completer<T> completer);
+
+ /// Add this result to an [EventSink].
+ ///
+ /// 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.
+ Future<T> get asFuture;
+}
diff --git a/lib/src/result/capture_sink.dart b/lib/src/result/capture_sink.dart
new file mode 100644
index 0000000..7474525
--- /dev/null
+++ b/lib/src/result/capture_sink.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import '../result.dart';
+
+/// Use [Result.captureSinkTransformer].
+@Deprecated("Will be removed in async 2.0.0.")
+class CaptureSink<T> implements EventSink<T> {
+ final EventSink _sink;
+
+ CaptureSink(EventSink<Result<T>> sink) : _sink = sink;
+
+ void add(T value) {
+ _sink.add(new Result.value(value));
+ }
+
+ void addError(Object error, [StackTrace stackTrace]) {
+ _sink.add(new Result.error(error, stackTrace));
+ }
+
+ void close() {
+ _sink.close();
+ }
+}
diff --git a/lib/src/result/capture_transformer.dart b/lib/src/result/capture_transformer.dart
new file mode 100644
index 0000000..ca4d0d3
--- /dev/null
+++ b/lib/src/result/capture_transformer.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import '../result.dart';
+import 'capture_sink.dart';
+
+/// Use [Result.captureTransformer] instead.
+@Deprecated("Will be removed in async 2.0.0.")
+class CaptureStreamTransformer<T> implements StreamTransformer<T, Result<T>> {
+ const CaptureStreamTransformer();
+
+ Stream<Result<T>> bind(Stream<T> source) {
+ return new Stream<Result<T>>.eventTransformed(source, _createSink);
+ }
+
+ static EventSink _createSink(EventSink<Result> sink) {
+ return new CaptureSink(sink);
+ }
+}
diff --git a/lib/src/result/error.dart b/lib/src/result/error.dart
new file mode 100644
index 0000000..eecf68e
--- /dev/null
+++ b/lib/src/result/error.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import '../result.dart';
+import 'value.dart';
+
+/// A result representing a thrown error.
+class ErrorResult implements Result {
+ final error;
+ final StackTrace stackTrace;
+
+ bool get isValue => false;
+ bool get isError => true;
+ ValueResult get asValue => null;
+ ErrorResult get asError => this;
+
+ ErrorResult(this.error, this.stackTrace);
+
+ void complete(Completer completer) {
+ completer.completeError(error, stackTrace);
+ }
+
+ void addTo(EventSink sink) {
+ sink.addError(error, stackTrace);
+ }
+
+ Future get asFuture => new Future.error(error, stackTrace);
+
+ /// Calls an error handler with the error and stacktrace.
+ ///
+ /// An async error handler function is either a function expecting two
+ /// arguments, which will be called with the error and the stack trace, or it
+ /// has to be a function expecting only one argument, which will be called
+ /// with only the error.
+ void handle(Function errorHandler) {
+ if (errorHandler is ZoneBinaryCallback) {
+ errorHandler(error, stackTrace);
+ } else {
+ errorHandler(error);
+ }
+ }
+}
diff --git a/lib/src/result_future.dart b/lib/src/result/future.dart
similarity index 93%
rename from lib/src/result_future.dart
rename to lib/src/result/future.dart
index 311e83f..db9dd82 100644
--- a/lib/src/result_future.dart
+++ b/lib/src/result/future.dart
@@ -2,12 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.result_future;
-
import 'dart:async';
+import '../delegate/future.dart';
import '../result.dart';
-import 'delegate/future.dart';
/// A [Future] wrapper that provides synchronous access to the result of the
/// wrapped [Future] once it's completed.
diff --git a/lib/src/result/release_sink.dart b/lib/src/result/release_sink.dart
new file mode 100644
index 0000000..114981b
--- /dev/null
+++ b/lib/src/result/release_sink.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import '../result.dart';
+
+/// Use [Result.captureSinkTransformer].
+@Deprecated("Will be removed in async 2.0.0.")
+class ReleaseSink<T> implements EventSink<Result<T>> {
+ final EventSink _sink;
+
+ ReleaseSink(EventSink<T> sink) : _sink = sink;
+
+ void add(Result<T> result) {
+ if (result.isValue) {
+ _sink.add(result.asValue.value);
+ } else {
+ var error = result.asError;
+ _sink.addError(error.error, error.stackTrace);
+ }
+ }
+
+ void addError(Object error, [StackTrace stackTrace]) {
+ // Errors may be added by intermediate processing, even if it is never
+ // added by CaptureSink.
+ _sink.addError(error, stackTrace);
+ }
+
+ void close() {
+ _sink.close();
+ }
+}
diff --git a/lib/src/result/release_transformer.dart b/lib/src/result/release_transformer.dart
new file mode 100644
index 0000000..456ed0a
--- /dev/null
+++ b/lib/src/result/release_transformer.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import '../result.dart';
+import 'release_sink.dart';
+
+/// Use [Result.releaseTransformer] instead.
+@Deprecated("Will be removed in async 2.0.0.")
+class ReleaseStreamTransformer<T> implements StreamTransformer<Result<T>, T> {
+ const ReleaseStreamTransformer();
+
+ Stream<T> bind(Stream<Result<T>> source) {
+ return new Stream<T>.eventTransformed(source, _createSink);
+ }
+
+ static EventSink<Result> _createSink(EventSink sink) {
+ return new ReleaseSink(sink);
+ }
+}
diff --git a/lib/src/result/value.dart b/lib/src/result/value.dart
new file mode 100644
index 0000000..f065ab6
--- /dev/null
+++ b/lib/src/result/value.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import '../result.dart';
+import 'error.dart';
+
+/// A result representing a returned value.
+class ValueResult<T> implements Result<T> {
+ final T value;
+
+ bool get isValue => true;
+ bool get isError => false;
+ ValueResult<T> get asValue => this;
+ ErrorResult get asError => null;
+
+ ValueResult(this.value);
+
+ void complete(Completer<T> completer) {
+ completer.complete(value);
+ }
+
+ void addTo(EventSink<T> sink) {
+ sink.add(value);
+ }
+
+ Future<T> get asFuture => new Future.value(value);
+}
diff --git a/lib/src/single_subscription_transformer.dart b/lib/src/single_subscription_transformer.dart
index 28fd512..4255175 100644
--- a/lib/src/single_subscription_transformer.dart
+++ b/lib/src/single_subscription_transformer.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.single_subscription_transformer;
-
import 'dart:async';
/// A transformer that converts a broadcast stream into a single-subscription
diff --git a/lib/src/stream_completer.dart b/lib/src/stream_completer.dart
index a6260dc..73557b2 100644
--- a/lib/src/stream_completer.dart
+++ b/lib/src/stream_completer.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.stream_completer;
-
import "dart:async";
/// A single-subscription [stream] where the contents are provided later.
diff --git a/lib/src/stream_group.dart b/lib/src/stream_group.dart
index d99f515..6239fc2 100644
--- a/lib/src/stream_group.dart
+++ b/lib/src/stream_group.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.stream_group;
-
import 'dart:async';
/// A collection of streams whose events are unified and sent through a central
diff --git a/lib/src/stream_queue.dart b/lib/src/stream_queue.dart
index 09b3a75..8482e0c 100644
--- a/lib/src/stream_queue.dart
+++ b/lib/src/stream_queue.dart
@@ -2,14 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.stream_events;
-
import 'dart:async';
import 'dart:collection';
+import "result.dart";
import "subscription_stream.dart";
import "stream_completer.dart";
-import "../result.dart";
/// An asynchronous pull-based interface for accessing stream events.
///
diff --git a/lib/src/stream_sink_completer.dart b/lib/src/stream_sink_completer.dart
index 0b6dc46..b53a8d2 100644
--- a/lib/src/stream_sink_completer.dart
+++ b/lib/src/stream_sink_completer.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.stream_sink_completer;
-
import 'dart:async';
import 'null_stream_sink.dart';
diff --git a/lib/src/stream_sink_transformer.dart b/lib/src/stream_sink_transformer.dart
index a8410ab..6cde04a 100644
--- a/lib/src/stream_sink_transformer.dart
+++ b/lib/src/stream_sink_transformer.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.stream_sink_transformer;
-
import 'dart:async';
import 'stream_sink_transformer/handler_transformer.dart';
diff --git a/lib/src/stream_sink_transformer/handler_transformer.dart b/lib/src/stream_sink_transformer/handler_transformer.dart
index e5d8e3c..a20a3fa 100644
--- a/lib/src/stream_sink_transformer/handler_transformer.dart
+++ b/lib/src/stream_sink_transformer/handler_transformer.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.stream_sink_transformer.handler_transformer;
-
import 'dart:async';
import '../stream_sink_transformer.dart';
diff --git a/lib/src/stream_sink_transformer/stream_transformer_wrapper.dart b/lib/src/stream_sink_transformer/stream_transformer_wrapper.dart
index b53f208..83d2b19 100644
--- a/lib/src/stream_sink_transformer/stream_transformer_wrapper.dart
+++ b/lib/src/stream_sink_transformer/stream_transformer_wrapper.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.stream_sink_transformer.stream_transformer_wrapper;
-
import 'dart:async';
import '../stream_sink_transformer.dart';
diff --git a/lib/src/stream_splitter.dart b/lib/src/stream_splitter.dart
index ac401a7..ec648aa 100644
--- a/lib/src/stream_splitter.dart
+++ b/lib/src/stream_splitter.dart
@@ -2,12 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.stream_splitter;
-
import 'dart:async';
-import '../result.dart';
import 'future_group.dart';
+import 'result.dart';
/// A class that splits a single source stream into an arbitrary number of
/// (single-subscription) streams (called "branch") that emit the same events.
diff --git a/lib/src/stream_zip.dart b/lib/src/stream_zip.dart
new file mode 100644
index 0000000..432cc22
--- /dev/null
+++ b/lib/src/stream_zip.dart
@@ -0,0 +1,120 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+
+/// A stream that combines the values of other streams.
+///
+/// This emits lists of collected values from each input stream. The first list
+/// contains the first value emitted by each stream, the second contrains the
+/// second value, and so on. The lists have the same ordering as the iterable
+/// passed to [new StreamZip].
+///
+/// Any errors from any of the streams are forwarded directly to this stream.
+class StreamZip<T> extends Stream<List<T>> {
+ final Iterable<Stream<T>> _streams;
+
+ StreamZip(Iterable<Stream<T>> streams) : _streams = streams;
+
+ StreamSubscription<List<T>> listen(void onData(List data), {
+ Function onError,
+ void onDone(),
+ bool cancelOnError}) {
+ cancelOnError = identical(true, cancelOnError);
+ List<StreamSubscription> subscriptions = <StreamSubscription>[];
+ StreamController controller;
+ List current;
+ int dataCount = 0;
+
+ /// Called for each data from a subscription in [subscriptions].
+ void handleData(int index, data) {
+ current[index] = data;
+ dataCount++;
+ if (dataCount == subscriptions.length) {
+ List data = current;
+ current = new List(subscriptions.length);
+ dataCount = 0;
+ for (int i = 0; i < subscriptions.length; i++) {
+ if (i != index) subscriptions[i].resume();
+ }
+ controller.add(data);
+ } else {
+ subscriptions[index].pause();
+ }
+ }
+
+ /// Called for each error from a subscription in [subscriptions].
+ /// Except if [cancelOnError] is true, in which case the function below
+ /// is used instead.
+ void handleError(Object error, StackTrace stackTrace) {
+ controller.addError(error, stackTrace);
+ }
+
+ /// Called when a subscription has an error and [cancelOnError] is true.
+ ///
+ /// Prematurely cancels all subscriptions since we know that we won't
+ /// be needing any more values.
+ void handleErrorCancel(Object error, StackTrace stackTrace) {
+ for (int i = 0; i < subscriptions.length; i++) {
+ subscriptions[i].cancel();
+ }
+ controller.addError(error, stackTrace);
+ }
+
+ void handleDone() {
+ for (int i = 0; i < subscriptions.length; i++) {
+ subscriptions[i].cancel();
+ }
+ controller.close();
+ }
+
+ try {
+ for (Stream stream in _streams) {
+ int index = subscriptions.length;
+ subscriptions.add(stream.listen(
+ (data) { handleData(index, data); },
+ onError: cancelOnError ? handleError : handleErrorCancel,
+ onDone: handleDone,
+ cancelOnError: cancelOnError));
+ }
+ } catch (e) {
+ for (int i = subscriptions.length - 1; i >= 0; i--) {
+ subscriptions[i].cancel();
+ }
+ rethrow;
+ }
+
+ current = new List(subscriptions.length);
+
+ controller = new StreamController<List>(
+ onPause: () {
+ for (int i = 0; i < subscriptions.length; i++) {
+ // This may pause some subscriptions more than once.
+ // These will not be resumed by onResume below, but must wait for the
+ // next round.
+ subscriptions[i].pause();
+ }
+ },
+ onResume: () {
+ for (int i = 0; i < subscriptions.length; i++) {
+ subscriptions[i].resume();
+ }
+ },
+ onCancel: () {
+ for (int i = 0; i < subscriptions.length; i++) {
+ // Canceling more than once is safe.
+ subscriptions[i].cancel();
+ }
+ }
+ );
+
+ if (subscriptions.isEmpty) {
+ controller.close();
+ }
+ return controller.stream.listen(onData,
+ onError: onError,
+ onDone: onDone,
+ cancelOnError: cancelOnError);
+ }
+}
diff --git a/lib/src/subscription_stream.dart b/lib/src/subscription_stream.dart
index bdf329b..4f58c76 100644
--- a/lib/src/subscription_stream.dart
+++ b/lib/src/subscription_stream.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.subscription_stream;
-
import 'dart:async';
import "delegate/stream_subscription.dart";
diff --git a/lib/stream_zip.dart b/lib/stream_zip.dart
index 055489d..cdeb5c9 100644
--- a/lib/stream_zip.dart
+++ b/lib/stream_zip.dart
@@ -2,118 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/**
- * Help for combining multiple streams into a single stream.
- */
+/// Import `async.dart` instead.
+@Deprecated("Will be removed in async 2.0.0.")
library dart.pkg.async.stream_zip;
-import "dart:async";
-
-/**
- * A stream that combines the values of other streams.
- */
-class StreamZip extends Stream<List> {
- final Iterable<Stream> _streams;
- StreamZip(Iterable<Stream> streams) : _streams = streams;
-
- StreamSubscription<List> listen(void onData(List data), {
- Function onError,
- void onDone(),
- bool cancelOnError}) {
- cancelOnError = identical(true, cancelOnError);
- List<StreamSubscription> subscriptions = <StreamSubscription>[];
- StreamController controller;
- List current;
- int dataCount = 0;
-
- /// Called for each data from a subscription in [subscriptions].
- void handleData(int index, data) {
- current[index] = data;
- dataCount++;
- if (dataCount == subscriptions.length) {
- List data = current;
- current = new List(subscriptions.length);
- dataCount = 0;
- for (int i = 0; i < subscriptions.length; i++) {
- if (i != index) subscriptions[i].resume();
- }
- controller.add(data);
- } else {
- subscriptions[index].pause();
- }
- }
-
- /// Called for each error from a subscription in [subscriptions].
- /// Except if [cancelOnError] is true, in which case the function below
- /// is used instead.
- void handleError(Object error, StackTrace stackTrace) {
- controller.addError(error, stackTrace);
- }
-
- /// Called when a subscription has an error and [cancelOnError] is true.
- ///
- /// Prematurely cancels all subscriptions since we know that we won't
- /// be needing any more values.
- void handleErrorCancel(Object error, StackTrace stackTrace) {
- for (int i = 0; i < subscriptions.length; i++) {
- subscriptions[i].cancel();
- }
- controller.addError(error, stackTrace);
- }
-
- void handleDone() {
- for (int i = 0; i < subscriptions.length; i++) {
- subscriptions[i].cancel();
- }
- controller.close();
- }
-
- try {
- for (Stream stream in _streams) {
- int index = subscriptions.length;
- subscriptions.add(stream.listen(
- (data) { handleData(index, data); },
- onError: cancelOnError ? handleError : handleErrorCancel,
- onDone: handleDone,
- cancelOnError: cancelOnError));
- }
- } catch (e) {
- for (int i = subscriptions.length - 1; i >= 0; i--) {
- subscriptions[i].cancel();
- }
- rethrow;
- }
-
- current = new List(subscriptions.length);
-
- controller = new StreamController<List>(
- onPause: () {
- for (int i = 0; i < subscriptions.length; i++) {
- // This may pause some subscriptions more than once.
- // These will not be resumed by onResume below, but must wait for the
- // next round.
- subscriptions[i].pause();
- }
- },
- onResume: () {
- for (int i = 0; i < subscriptions.length; i++) {
- subscriptions[i].resume();
- }
- },
- onCancel: () {
- for (int i = 0; i < subscriptions.length; i++) {
- // Canceling more than once is safe.
- subscriptions[i].cancel();
- }
- }
- );
-
- if (subscriptions.isEmpty) {
- controller.close();
- }
- return controller.stream.listen(onData,
- onError: onError,
- onDone: onDone,
- cancelOnError: cancelOnError);
- }
-}
+export "src/stream_zip.dart";
diff --git a/pubspec.yaml b/pubspec.yaml
index 7560836..2430d75 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: async
-version: 1.8.0
+version: 1.9.0
author: Dart Team <misc@dartlang.org>
description: Utility functions and classes related to the 'dart:async' library.
homepage: https://www.github.com/dart-lang/async
diff --git a/test/result_test.dart b/test/result_test.dart
index 848c455..7af3fcf 100644
--- a/test/result_test.dart
+++ b/test/result_test.dart
@@ -5,7 +5,7 @@
import "dart:async";
import "dart:collection";
-import "package:async/result.dart";
+import "package:async/async.dart";
import "package:stack_trace/stack_trace.dart";
import "package:test/test.dart";
diff --git a/test/stream_group_test.dart b/test/stream_group_test.dart
index db6c938..5078dad 100644
--- a/test/stream_group_test.dart
+++ b/test/stream_group_test.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library async.test.stream_group_test;
-
import 'dart:async';
import 'package:async/async.dart';
diff --git a/test/stream_zip_test.dart b/test/stream_zip_test.dart
index 35ace7d..47f3d8d 100644
--- a/test/stream_zip_test.dart
+++ b/test/stream_zip_test.dart
@@ -3,7 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import "dart:async";
-import "package:async/stream_zip.dart";
+
+import "package:async/async.dart";
import "package:test/test.dart";
/// Create an error with the same values as [base], except that it throwsA
diff --git a/test/utils.dart b/test/utils.dart
index 445b9fc..c32ea2c 100644
--- a/test/utils.dart
+++ b/test/utils.dart
@@ -3,8 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
/// Helper utilities for testing.
-library async.test.util;
-
import "dart:async";
import "package:async/async.dart";