LCOV - code coverage report
Current view: top level - src - extensions.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 34 35 97.1 %
Date: 2021-09-23 09:51:56 Functions: 0 0 -

          Line data    Source code
       1             : part of 'bloc/rx_bloc_base.dart';
       2             : 
       3             : /// ResultErrorStream utility extension methods.
       4             : extension ResultErrorStream<T> on Stream<ResultError<T>> {
       5             :   /// Map the ResultError to the the exception that holds
       6           4 :   Stream<Exception> mapToException() => map((error) => error.error);
       7             : 
       8             :   /// Map the ResultError to the the exception that holds
       9           1 :   Stream<ErrorWithTag> mapToErrorWithTag() =>
      10           3 :       map((error) => ErrorWithTag.fromResult(error));
      11             : }
      12             : 
      13             : /// ResultStream utility extension methods.
      14             : extension ResultStream<T> on Stream<Result<T>> {
      15             :   /// Finds the [ResultSuccess] as unwraps the [ResultSuccess.data] from it.
      16             :   ///
      17             :   /// It filters the other types of [Result] such as
      18             :   /// [ResultError] and [ResultLoading].
      19           2 :   Stream<T> whereSuccess() =>
      20           8 :       whereType<ResultSuccess<T>>().map((data) => data.data);
      21             : 
      22             :   /// Finds the [ResultError] as unwraps the [ResultError.error] from it.
      23             :   ///
      24             :   /// It filters the other types of [Result] such as
      25             :   /// [ResultSuccess] and [ResultLoading].
      26           1 :   Stream<Exception> whereError() =>
      27           4 :       whereType<ResultError<T>>().map((error) => error.error);
      28             : 
      29             :   /// Returns `true` if the [Result] is [ResultLoading],
      30             :   /// otherwise returns `false`
      31           4 :   Stream<bool> isLoading() => map((data) => data is ResultLoading);
      32             : 
      33             :   /// Returns a container []
      34           4 :   Stream<LoadingWithTag> isLoadingWithTag() => map((data) => LoadingWithTag(
      35           1 :         loading: data is ResultLoading,
      36           1 :         tag: data.tag,
      37             :       ));
      38             : }
      39             : 
      40             : /// Result utility extension methods.
      41             : extension AsResultStream<T> on Stream<T> {
      42             :   /// Converts the [Stream] to a [Stream] of [Result]
      43             :   ///
      44             :   /// As soon as the [Stream] is being subscribed it emits
      45             :   /// [ResultLoading] immediately,
      46             :   /// as afterwards emits either [ResultError] or [ResultSuccess]
      47           2 :   Stream<Result<T>> asResultStream({
      48             :     String tag = '',
      49             :   }) =>
      50           6 :       map((data) => Result<T>.success(data, tag: tag))
      51           2 :           .onErrorReturnWith(
      52           4 :             (error, stacktrace) => Result<T>.error(
      53           2 :               error is Exception ? error : Exception(error.toString()),
      54             :               tag: tag,
      55             :             ),
      56             :           )
      57           4 :           .startWith(Result<T>.loading(tag: tag));
      58             : }
      59             : 
      60             : /// Future asResultStream utilities
      61             : extension FutureAsResultStream<T> on Future<T> {
      62             :   /// Converts the [Future] to a [Stream] of [Result]
      63             :   ///
      64             :   /// As soon as the [Stream] is being subscribed it emits
      65             :   /// [ResultLoading] immediately,
      66             :   /// as afterwards emits either [ResultError] or [ResultSuccess]
      67           2 :   Stream<Result<T>> asResultStream({String tag = ''}) =>
      68           4 :       asStream().asResultStream(tag: tag);
      69             : }
      70             : 
      71             : /// Stream loading and error handlers
      72             : extension HandleByRxBlocBase<T> on Stream<Result<T>> {
      73             :   /// Handle [ResultLoading] states from stream.
      74             :   ///
      75             :   /// Once the states are being handled they sink to [RxBlocBase.loadingState].
      76             :   /// Converts the stream to broadcast one based on [shareReplay].
      77             :   ///
      78             :   /// In case you need to handle error states along with the loading state,
      79             :   /// use [setResultStateHandler] instead.
      80           1 :   Stream<Result<T>> setLoadingStateHandler(
      81             :     RxBlocBase bloc, {
      82             :     bool shareReplay = true,
      83             :   }) =>
      84           1 :       doOnData(
      85           3 :         (event) => bloc._loadingBloc.setResult(
      86             :           result: event,
      87             :         ),
      88           1 :       ).asSharedStream(shareReplay: shareReplay);
      89             : 
      90             :   /// Handle [ResultError] states from the stream.
      91             :   ///
      92             :   /// Once the states are being handled they sink to [RxBlocBase.errorState].
      93             :   /// Converts the stream to broadcast one based on [shareReplay].
      94             :   ///
      95             :   /// In case you need to register loading states along with the exceptions,
      96             :   /// use [setResultStateHandler] instead.
      97           1 :   Stream<Result<T>> setErrorStateHandler(
      98             :     RxBlocBase bloc, {
      99             :     bool shareReplay = true,
     100             :   }) =>
     101           2 :       doOnData((event) {
     102           1 :         if (event is ResultError<T>) {
     103           3 :           bloc._resultStreamExceptionsSubject.sink.add(event);
     104             :         }
     105           1 :       }).asSharedStream(shareReplay: shareReplay);
     106             : 
     107             :   /// Handle [ResultLoading] and [ResultError] by a BLoC.
     108             :   ///
     109             :   /// Converts the stream to broadcast one based on [shareReplay].
     110             :   ///
     111             :   /// Useful when multiple type of result streams are executed by a single Bloc,
     112             :   /// as all [ResultError] and [ResultLoading] states resides in a central place
     113             :   ///
     114             :   /// Once [ResultLoading] states are being handled
     115             :   /// they sink to [RxBlocBase.loadingState].
     116             :   /// Once [ResultError] states are being handled
     117             :   /// they sink to [RxBlocBase.errorState].
     118           1 :   Stream<Result<T>> setResultStateHandler(RxBlocBase bloc,
     119             :           {bool shareReplay = true}) =>
     120           1 :       setErrorStateHandler(bloc)
     121           1 :           .setLoadingStateHandler(bloc)
     122           1 :           .asSharedStream(shareReplay: shareReplay);
     123             : }
     124             : 
     125             : /// Stream binder utilities
     126             : extension Bind<T> on Stream<T> {
     127             :   /// Bind a stream to the given subject [subject].
     128             :   ///
     129             :   /// Each event from the stream will be added to the subject, meaning that the
     130             :   /// both needs to be of the same type.
     131             :   /// Be aware that the binding is facilitating the subscribing, so the
     132             :   /// unsubscribing needs to be handled accordingly either by
     133             :   /// using [CompositeSubscription] or manually.
     134           0 :   StreamSubscription<T> bind(Subject<T> subject) => listen(subject.sink.add);
     135             : }
     136             : 
     137             : /// Stream subscription disposer
     138             : extension DisposedBy<T> on StreamSubscription<T> {
     139             :   /// Add the stream to [compositeSubscription].
     140             :   ///
     141             :   /// Once [compositeSubscription] is being disposed all added subscriptions
     142             :   /// will be disposed automatically
     143           1 :   StreamSubscription<T> disposedBy(
     144             :           CompositeSubscription compositeSubscription) =>
     145           1 :       compositeSubscription.add(this);
     146             : }

Generated by: LCOV version 1.15