mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:39:49 +00:00
b8cd8eee5d
Also caught a couple of mistakes I made in dart:collection which got picked up by this because some classes in here use classes from there. Change-Id: I799db57baf4ea97e8ad4700008918acf03956aff Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/123600 Commit-Queue: Bob Nystrom <rnystrom@google.com> Auto-Submit: Bob Nystrom <rnystrom@google.com> Reviewed-by: Leaf Petersen <leafp@google.com> Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
126 lines
3.7 KiB
Dart
126 lines
3.7 KiB
Dart
// Copyright (c) 2012, 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.
|
|
|
|
part of dart._internal;
|
|
|
|
// Casting wrappers for asynchronous classes.
|
|
|
|
class CastStream<S, T> extends Stream<T> {
|
|
final Stream<S> _source;
|
|
CastStream(this._source);
|
|
bool get isBroadcast => _source.isBroadcast;
|
|
|
|
StreamSubscription<T> listen(void Function(T data)? onData,
|
|
{Function? onError, void Function()? onDone, bool? cancelOnError}) {
|
|
return new CastStreamSubscription<S, T>(
|
|
_source.listen(null, onDone: onDone, cancelOnError: cancelOnError))
|
|
..onData(onData)
|
|
..onError(onError);
|
|
}
|
|
|
|
Stream<R> cast<R>() => new CastStream<S, R>(_source);
|
|
}
|
|
|
|
class CastStreamSubscription<S, T> implements StreamSubscription<T> {
|
|
final StreamSubscription<S> _source;
|
|
|
|
/// Zone where listen was called.
|
|
final Zone _zone = Zone.current;
|
|
|
|
/// User's data handler.
|
|
void Function(T)? _handleData;
|
|
|
|
/// Copy of _source's handleError so we can report errors in onData.
|
|
Function? _handleError;
|
|
|
|
CastStreamSubscription(this._source) {
|
|
_source.onData(_onData);
|
|
}
|
|
|
|
Future cancel() => _source.cancel();
|
|
|
|
void onData(void Function(T data)? handleData) {
|
|
_handleData = handleData == null
|
|
? null
|
|
: _zone.registerUnaryCallback<dynamic, T>(handleData);
|
|
}
|
|
|
|
void onError(Function? handleError) {
|
|
_source.onError(handleError);
|
|
if (handleError == null) {
|
|
_handleError = null;
|
|
} else if (handleError is void Function(Object, StackTrace?)) {
|
|
_handleError = _zone
|
|
.registerBinaryCallback<dynamic, Object, StackTrace?>(handleError);
|
|
} else if (handleError is void Function(Object)) {
|
|
_handleError = _zone.registerUnaryCallback<dynamic, Object>(handleError);
|
|
} else {
|
|
throw ArgumentError("handleError callback must take either an Object "
|
|
"(the error), or both an Object (the error) and a StackTrace.");
|
|
}
|
|
}
|
|
|
|
void onDone(void handleDone()?) {
|
|
_source.onDone(handleDone);
|
|
}
|
|
|
|
void _onData(S data) {
|
|
if (_handleData == null) return;
|
|
T targetData;
|
|
try {
|
|
targetData = data as T;
|
|
} catch (error, stack) {
|
|
var handleError = _handleError;
|
|
if (handleError == null) {
|
|
_zone.handleUncaughtError(error, stack);
|
|
} else if (handleError is void Function(Object, StackTrace?)) {
|
|
_zone.runBinaryGuarded<Object, StackTrace?>(handleError, error, stack);
|
|
} else {
|
|
_zone.runUnaryGuarded<Object>(
|
|
handleError as void Function(Object), error);
|
|
}
|
|
return;
|
|
}
|
|
_zone.runUnaryGuarded(_handleData!, targetData);
|
|
}
|
|
|
|
void pause([Future? resumeSignal]) {
|
|
_source.pause(resumeSignal);
|
|
}
|
|
|
|
void resume() {
|
|
_source.resume();
|
|
}
|
|
|
|
bool get isPaused => _source.isPaused;
|
|
|
|
Future<E> asFuture<E>([E? futureValue]) => _source.asFuture<E>(futureValue);
|
|
}
|
|
|
|
class CastStreamTransformer<SS, ST, TS, TT>
|
|
extends StreamTransformerBase<TS, TT> {
|
|
final StreamTransformer<SS, ST> _source;
|
|
CastStreamTransformer(this._source);
|
|
|
|
StreamTransformer<RS, RT> cast<RS, RT>() =>
|
|
new CastStreamTransformer<SS, ST, RS, RT>(_source);
|
|
Stream<TT> bind(Stream<TS> stream) =>
|
|
_source.bind(stream.cast<SS>()).cast<TT>();
|
|
}
|
|
|
|
class CastConverter<SS, ST, TS, TT> extends Converter<TS, TT> {
|
|
final Converter<SS, ST> _source;
|
|
CastConverter(this._source);
|
|
|
|
TT convert(TS input) => _source.convert(input as SS) as TT;
|
|
|
|
// cast is inherited from Converter.
|
|
|
|
Stream<TT> bind(Stream<TS> stream) =>
|
|
_source.bind(stream.cast<SS>()).cast<TT>();
|
|
|
|
Converter<RS, RT> cast<RS, RT>() =>
|
|
new CastConverter<SS, ST, RS, RT>(_source);
|
|
}
|