Add type-coercion functions.
These match (and are based on) the coercion functions in
dart-lang/async.
R=sigmund@google.com
Review URL: https://codereview.chromium.org//1966853003 .
diff --git a/.analysis_options b/.analysis_options
new file mode 100644
index 0000000..a10d4c5
--- /dev/null
+++ b/.analysis_options
@@ -0,0 +1,2 @@
+analyzer:
+ strong-mode: true
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a5a7e46..6d86e48 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 1.4.0
+
+* Add `StreamChannel.cast()`, which soundly coerces the generic type of a
+ channel.
+
+* Add `StreamChannelTransformer.typed()`, which soundly coerces the generic type
+ of a transformer.
+
## 1.3.2
* Fix all strong-mode errors and warnings.
diff --git a/lib/src/stream_channel_transformer.dart b/lib/src/stream_channel_transformer.dart
index ac98085..ca09ea1 100644
--- a/lib/src/stream_channel_transformer.dart
+++ b/lib/src/stream_channel_transformer.dart
@@ -8,6 +8,7 @@
import 'package:async/async.dart';
import '../stream_channel.dart';
+import 'transformer/typed.dart';
/// A [StreamChannelTransformer] transforms the events being passed to and
/// emitted by a [StreamChannel].
@@ -24,6 +25,21 @@
/// The transformer to use on the channel's sink.
final StreamSinkTransformer<S, T> _sinkTransformer;
+ /// Creates a wrapper that coerces the type of [transformer].
+ ///
+ /// This soundly converts a [StreamChannelTransformer] to a
+ /// `StreamChannelTransformer<S, T>`, regardless of its original generic type,
+ /// by asserting that the events emitted by the transformed channel's stream
+ /// are instances of `T` whenever they're provided. If they're not, the stream
+ /// throws a [CastError]. This also means that calls to [StreamSink.add] on
+ /// the transformed channel's sink may throw a [CastError] if the argument
+ /// type doesn't match the reified type of the sink.
+ static StreamChannelTransformer/*<S, T>*/ typed/*<S, T>*/(
+ StreamChannelTransformer transformer) =>
+ transformer is StreamChannelTransformer/*<S, T>*/
+ ? transformer
+ : new TypeSafeStreamChannelTransformer(transformer);
+
/// Creates a [StreamChannelTransformer] from existing stream and sink
/// transformers.
const StreamChannelTransformer(
diff --git a/lib/src/transformer/typed.dart b/lib/src/transformer/typed.dart
new file mode 100644
index 0000000..f35e01c
--- /dev/null
+++ b/lib/src/transformer/typed.dart
@@ -0,0 +1,17 @@
+// 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 '../../stream_channel.dart';
+
+/// A wrapper that coerces the generic type of the channel returned by an inner
+/// transformer to `S`.
+class TypeSafeStreamChannelTransformer<S, T>
+ implements StreamChannelTransformer<S, T> {
+ final StreamChannelTransformer _inner;
+
+ TypeSafeStreamChannelTransformer(this._inner);
+
+ StreamChannel<S> bind(StreamChannel<T> channel) =>
+ _inner.bind(channel).cast();
+}
diff --git a/lib/stream_channel.dart b/lib/stream_channel.dart
index b89845d..3615d21 100644
--- a/lib/stream_channel.dart
+++ b/lib/stream_channel.dart
@@ -109,6 +109,13 @@
/// Returns a copy of [this] with [sink] replaced by [change]'s return
/// value.
StreamChannel<T> changeSink(StreamSink<T> change(StreamSink<T> sink));
+
+ /// Returns a copy of [this] with the generic type coerced to [S].
+ ///
+ /// If any events emitted by [stream] aren't of type [S], they're converted
+ /// into [CastError] events. Similarly, if any events are added to [sync] that
+ /// aren't of type [S], a [CastError] is thrown.
+ StreamChannel/*<S>*/ cast/*<S>*/();
}
/// An implementation of [StreamChannel] that simply takes a stream and a sink
@@ -145,4 +152,7 @@
StreamChannel<T> changeSink(StreamSink<T> change(StreamSink<T> sink)) =>
new StreamChannel(stream, change(sink));
+
+ StreamChannel/*<S>*/ cast/*<S>*/() => new StreamChannel(
+ DelegatingStream.typed(stream), DelegatingStreamSink.typed(sink));
}
diff --git a/pubspec.yaml b/pubspec.yaml
index 3e87e2b..1c1df31 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: stream_channel
-version: 1.3.2
+version: 1.4.0
description: An abstraction for two-way communication channels.
author: Dart Team <misc@dartlang.org>
homepage: https://github.com/dart-lang/stream_channel