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