LCOV - code coverage report
Current view: top level - stream_channel-2.1.0/lib - stream_channel.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 5 23 21.7 %
Date: 2021-11-28 14:37:50 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
       2             : // for details. All rights reserved. Use of this source code is governed by a
       3             : // BSD-style license that can be found in the LICENSE file.
       4             : 
       5             : import 'dart:async';
       6             : 
       7             : import 'package:async/async.dart';
       8             : 
       9             : import 'src/guarantee_channel.dart';
      10             : import 'src/close_guarantee_channel.dart';
      11             : import 'src/stream_channel_transformer.dart';
      12             : 
      13             : export 'src/delegating_stream_channel.dart';
      14             : export 'src/disconnector.dart';
      15             : export 'src/json_document_transformer.dart';
      16             : export 'src/multi_channel.dart';
      17             : export 'src/stream_channel_completer.dart';
      18             : export 'src/stream_channel_controller.dart';
      19             : export 'src/stream_channel_transformer.dart';
      20             : 
      21             : /// An abstract class representing a two-way communication channel.
      22             : ///
      23             : /// Users should consider the [stream] emitting a "done" event to be the
      24             : /// canonical indicator that the channel has closed. If they wish to close the
      25             : /// channel, they should close the [sink]—canceling the stream subscription is
      26             : /// not sufficient. Protocol errors may be emitted through the stream or through
      27             : /// [sink].done, depending on their underlying cause. Note that the sink may
      28             : /// silently drop events if the channel closes before [sink].close is called.
      29             : ///
      30             : /// Implementations are strongly encouraged to mix in or extend
      31             : /// [StreamChannelMixin] to get default implementations of the various instance
      32             : /// methods. Adding new methods to this interface will not be considered a
      33             : /// breaking change if implementations are also added to [StreamChannelMixin].
      34             : ///
      35             : /// Implementations must provide the following guarantees:
      36             : ///
      37             : /// * The stream is single-subscription, and must follow all the guarantees of
      38             : ///   single-subscription streams.
      39             : ///
      40             : /// * Closing the sink causes the stream to close before it emits any more
      41             : ///   events.
      42             : ///
      43             : /// * After the stream closes, the sink is automatically closed. If this
      44             : ///   happens, sink methods should silently drop their arguments until
      45             : ///   [sink].close is called.
      46             : ///
      47             : /// * If the stream closes before it has a listener, the sink should silently
      48             : ///   drop events if possible.
      49             : ///
      50             : /// * Canceling the stream's subscription has no effect on the sink. The channel
      51             : ///   must still be able to respond to the other endpoint closing the channel
      52             : ///   even after the subscription has been canceled.
      53             : ///
      54             : /// * The sink *either* forwards errors to the other endpoint *or* closes as
      55             : ///   soon as an error is added and forwards that error to the [sink].done
      56             : ///   future.
      57             : ///
      58             : /// These guarantees allow users to interact uniformly with all implementations,
      59             : /// and ensure that either endpoint closing the stream produces consistent
      60             : /// behavior.
      61             : abstract class StreamChannel<T> {
      62             :   /// The single-subscription stream that emits values from the other endpoint.
      63             :   Stream<T> get stream;
      64             : 
      65             :   /// The sink for sending values to the other endpoint.
      66             :   StreamSink<T> get sink;
      67             : 
      68             :   /// Creates a new [StreamChannel] that communicates over [stream] and [sink].
      69             :   ///
      70             :   /// Note that this stream/sink pair must provide the guarantees listed in the
      71             :   /// [StreamChannel] documentation. If they don't do so natively,
      72             :   /// [StreamChannel.withGuarantees] should be used instead.
      73           0 :   factory StreamChannel(Stream<T> stream, StreamSink<T> sink) =>
      74           0 :       _StreamChannel<T>(stream, sink);
      75             : 
      76             :   /// Creates a new [StreamChannel] that communicates over [stream] and [sink].
      77             :   ///
      78             :   /// Unlike [new StreamChannel], this enforces the guarantees listed in the
      79             :   /// [StreamChannel] documentation. This makes it somewhat less efficient than
      80             :   /// just wrapping a stream and a sink directly, so [new StreamChannel] should
      81             :   /// be used when the guarantees are provided natively.
      82             :   ///
      83             :   /// If [allowSinkErrors] is `false`, errors are not allowed to be passed to
      84             :   /// [sink]. If any are, the connection will close and the error will be
      85             :   /// forwarded to [sink].done.
      86          11 :   factory StreamChannel.withGuarantees(Stream<T> stream, StreamSink<T> sink,
      87             :           {bool allowSinkErrors = true}) =>
      88          11 :       GuaranteeChannel(stream, sink, allowSinkErrors: allowSinkErrors);
      89             : 
      90             :   /// Creates a new [StreamChannel] that communicates over [stream] and [sink].
      91             :   ///
      92             :   /// This specifically enforces the second guarantee: closing the sink causes
      93             :   /// the stream to close before it emits any more events. This guarantee is
      94             :   /// invalidated when an asynchronous gap is added between the original
      95             :   /// stream's event dispatch and the returned stream's, for example by
      96             :   /// transforming it with a [StreamTransformer]. This is a lighter-weight way
      97             :   /// of preserving that guarantee in particular than
      98             :   /// [StreamChannel.withGuarantees].
      99           0 :   factory StreamChannel.withCloseGuarantee(
     100             :           Stream<T> stream, StreamSink<T> sink) =>
     101           0 :       CloseGuaranteeChannel(stream, sink);
     102             : 
     103             :   /// Connects this to [other], so that any values emitted by either are sent
     104             :   /// directly to the other.
     105             :   void pipe(StreamChannel<T> other);
     106             : 
     107             :   /// Transforms this using [transformer].
     108             :   ///
     109             :   /// This is identical to calling `transformer.bind(channel)`.
     110             :   StreamChannel<S> transform<S>(StreamChannelTransformer<S, T> transformer);
     111             : 
     112             :   /// Transforms only the [stream] component of this using [transformer].
     113             :   StreamChannel<T> transformStream(StreamTransformer<T, T> transformer);
     114             : 
     115             :   /// Transforms only the [sink] component of this using [transformer].
     116             :   StreamChannel<T> transformSink(StreamSinkTransformer<T, T> transformer);
     117             : 
     118             :   /// Returns a copy of this with [stream] replaced by [change]'s return
     119             :   /// value.
     120             :   StreamChannel<T> changeStream(Stream<T> Function(Stream<T>) change);
     121             : 
     122             :   /// Returns a copy of this with [sink] replaced by [change]'s return
     123             :   /// value.
     124             :   StreamChannel<T> changeSink(StreamSink<T> Function(StreamSink<T>) change);
     125             : 
     126             :   /// Returns a copy of this with the generic type coerced to [S].
     127             :   ///
     128             :   /// If any events emitted by [stream] aren't of type [S], they're converted
     129             :   /// into [TypeError] events (`CastError` on some SDK versions). Similarly, if
     130             :   /// any events are added to [sink] that aren't of type [S], a [TypeError] is
     131             :   /// thrown.
     132             :   StreamChannel<S> cast<S>();
     133             : }
     134             : 
     135             : /// An implementation of [StreamChannel] that simply takes a stream and a sink
     136             : /// as parameters.
     137             : ///
     138             : /// This is distinct from [StreamChannel] so that it can use
     139             : /// [StreamChannelMixin].
     140             : class _StreamChannel<T> extends StreamChannelMixin<T> {
     141             :   @override
     142             :   final Stream<T> stream;
     143             :   @override
     144             :   final StreamSink<T> sink;
     145             : 
     146           0 :   _StreamChannel(this.stream, this.sink);
     147             : }
     148             : 
     149             : /// A mixin that implements the instance methods of [StreamChannel] in terms of
     150             : /// [stream] and [sink].
     151             : abstract class StreamChannelMixin<T> implements StreamChannel<T> {
     152          11 :   @override
     153             :   void pipe(StreamChannel<T> other) {
     154          33 :     stream.pipe(other.sink);
     155          33 :     other.stream.pipe(sink);
     156             :   }
     157             : 
     158           0 :   @override
     159             :   StreamChannel<S> transform<S>(StreamChannelTransformer<S, T> transformer) =>
     160           0 :       transformer.bind(this);
     161             : 
     162           0 :   @override
     163             :   StreamChannel<T> transformStream(StreamTransformer<T, T> transformer) =>
     164           0 :       changeStream(transformer.bind);
     165             : 
     166           0 :   @override
     167             :   StreamChannel<T> transformSink(StreamSinkTransformer<T, T> transformer) =>
     168           0 :       changeSink(transformer.bind);
     169             : 
     170           0 :   @override
     171             :   StreamChannel<T> changeStream(Stream<T> Function(Stream<T>) change) =>
     172           0 :       StreamChannel.withCloseGuarantee(change(stream), sink);
     173             : 
     174           0 :   @override
     175             :   StreamChannel<T> changeSink(StreamSink<T> Function(StreamSink<T>) change) =>
     176           0 :       StreamChannel.withCloseGuarantee(stream, change(sink));
     177             : 
     178           0 :   @override
     179           0 :   StreamChannel<S> cast<S>() => StreamChannel(
     180           0 :       stream.cast(), StreamController(sync: true)..stream.cast<T>().pipe(sink));
     181             : }

Generated by: LCOV version 1.14