Add APIs for asserting the types of transformers.
I thought about adding these to Delegating*Transformer classes, but
those delegates don't really make any sense at all on their own, so I
found other places instead.
R=lrn@google.com
Review URL: https://codereview.chromium.org//1947923003 .
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b18365f..de22933 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+## 1.11.0
+
+* Add a `typedStreamTransformer()` function. This wraps an untyped
+ `StreamTransformer` with the correct type parameters, and asserts the types of
+ events as they're emitted from the transformed stream.
+
+* Add a `StreamSinkTransformer.typed()` static method. This wraps an untyped
+ `StreamSinkTransformer` with the correct type parameters, and asserts the
+ types of arguments passed in to the resulting sink.
+
## 1.10.0
* Add `DelegatingFuture.typed()`, `DelegatingStreamSubscription.typed()`,
diff --git a/lib/async.dart b/lib/async.dart
index 7055341..8218986 100644
--- a/lib/async.dart
+++ b/lib/async.dart
@@ -30,3 +30,4 @@
export "src/stream_splitter.dart";
export "src/stream_zip.dart";
export "src/subscription_stream.dart";
+export "src/typed_stream_transformer.dart";
diff --git a/lib/src/stream_sink_transformer.dart b/lib/src/stream_sink_transformer.dart
index 6cde04a..d40bc4b 100644
--- a/lib/src/stream_sink_transformer.dart
+++ b/lib/src/stream_sink_transformer.dart
@@ -6,6 +6,7 @@
import 'stream_sink_transformer/handler_transformer.dart';
import 'stream_sink_transformer/stream_transformer_wrapper.dart';
+import 'stream_sink_transformer/typed.dart';
/// A [StreamSinkTransformer] transforms the events being passed to a sink.
///
@@ -45,4 +46,17 @@
/// Creates a new sink. When events are passed to the returned sink, it will
/// transform them and pass the transformed versions to [sink].
StreamSink<S> bind(StreamSink<T> sink);
+
+ /// Creates a wrapper that coerces the type of [transformer].
+ ///
+ /// This soundly converts a [StreamSinkTransformer] to a
+ /// `StreamSinkTransformer<S, T>`, regardless of its original generic type.
+ /// This means that calls to [StreamSink.add] on the returned sink may throw a
+ /// [CastError] if the argument type doesn't match the reified type of the
+ /// sink.
+ static StreamSinkTransformer/*<S, T>*/ typed/*<S, T>*/(
+ StreamSinkTransformer transformer) =>
+ transformer is StreamSinkTransformer/*<S, T>*/
+ ? transformer
+ : new TypeSafeStreamSinkTransformer(transformer);
}
diff --git a/lib/src/stream_sink_transformer/typed.dart b/lib/src/stream_sink_transformer/typed.dart
new file mode 100644
index 0000000..303bc08
--- /dev/null
+++ b/lib/src/stream_sink_transformer/typed.dart
@@ -0,0 +1,20 @@
+// 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 '../delegate/stream_sink.dart';
+import '../stream_sink_transformer.dart';
+
+/// A wrapper that coerces the generic type of the sink returned by an inner
+/// transformer to `S`.
+class TypeSafeStreamSinkTransformer<S, T>
+ implements StreamSinkTransformer<S, T> {
+ final StreamSinkTransformer _inner;
+
+ TypeSafeStreamSinkTransformer(this._inner);
+
+ StreamSink<S> bind(StreamSink<T> sink) =>
+ DelegatingStreamSink.typed(_inner.bind(sink));
+}
diff --git a/lib/src/typed_stream_transformer.dart b/lib/src/typed_stream_transformer.dart
new file mode 100644
index 0000000..2fb20c4
--- /dev/null
+++ b/lib/src/typed_stream_transformer.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 'delegate/stream.dart';
+
+/// Creates a wrapper that coerces the type of [transformer].
+///
+/// This soundly converts a [StreamTransformer] to a `StreamTransformer<S, T>`,
+/// regardless of its original generic type, by asserting that the events
+/// emitted by the transformed stream are instances of `T` whenever they're
+/// provided. If they're not, the stream throws a [CastError].
+StreamTransformer/*<S, T>*/ typedStreamTransformer/*<S, T>*/(
+ StreamTransformer transformer) =>
+ transformer is StreamTransformer/*<S, T>*/
+ ? transformer
+ : new _TypeSafeStreamTransformer(transformer);
+
+/// A wrapper that coerces the type of the stream returned by an inner
+/// transformer.
+class _TypeSafeStreamTransformer<S, T> implements StreamTransformer<S, T> {
+ final StreamTransformer _inner;
+
+ _TypeSafeStreamTransformer(this._inner);
+
+ Stream<T> bind(Stream<S> stream) =>
+ DelegatingStream.typed(_inner.bind(stream));
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index 0859e29..c6843a4 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: async
-version: 1.10.0
+version: 1.11.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