LCOV - code coverage report
Current view: top level - lib/provider - filters.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 30 30 100.0 %
Date: 2023-10-11 10:27:27 Functions: 0 0 -

          Line data    Source code
       1             : import '../notifiers/state_notifier.dart';
       2             : import 'state_notifier_provider.dart';
       3             : 
       4             : typedef SelectCallback<S, R> = R Function(S);
       5             : typedef BuildWhenCallback<S> = bool Function(S prev, S current);
       6             : 
       7             : sealed class FilteredProvider<N, S> {
       8           2 :   FilteredProvider({required this.notifier});
       9             : 
      10             :   final N notifier;
      11             : 
      12             :   /// function to rebuild the Consumer
      13             :   void Function(N notifier)? reaction;
      14             : 
      15             :   late void Function(S) listener;
      16             :   void createListener();
      17             : }
      18             : 
      19             : class SelectFilteredProvider<N extends StateNotifier<S>, S, R>
      20             :     extends FilteredProvider<N, S> implements BaseStateNotifierProvider<N, S> {
      21           2 :   SelectFilteredProvider({
      22             :     required super.notifier,
      23             :     required this.callback,
      24             :     required this.listenWhenTheCallbackReturnsTrue,
      25             :   });
      26             : 
      27             :   /// callback defined when a filter is used
      28             :   final SelectCallback<S, R> callback;
      29             : 
      30             :   /// if the filter is a selected and we only want to
      31             :   /// rebuild the consumer when the callback returns true
      32             :   final bool listenWhenTheCallbackReturnsTrue;
      33             : 
      34             :   /// used to store the value returned by .select or .when
      35             :   late R selectValue;
      36             : 
      37           2 :   @override
      38           2 :   void createListener() => createSelectListener(this);
      39             : }
      40             : 
      41             : class WhenFilteredProvider<N extends StateNotifier<S>, S>
      42             :     extends FilteredProvider<N, S> implements BaseStateNotifierProvider<N, S> {
      43           2 :   WhenFilteredProvider({
      44             :     required super.notifier,
      45             :     required this.callback,
      46             :   });
      47             : 
      48             :   /// callback defined when a filter is used
      49             :   final BuildWhenCallback<S> callback;
      50             : 
      51           2 :   @override
      52           2 :   void createListener() => createWhenListener(this);
      53             : }
      54             : 
      55             : extension StateNotifierProviderExtension<N extends StateNotifier<S>, S, A>
      56             :     on ListeneableProvider<N, S, A> {
      57           2 :   SelectFilteredProvider<N, S, R> select<R>(
      58             :     SelectCallback<S, R> callback, {
      59             :     String? tag,
      60             :     bool booleanCallback = false,
      61             :   }) {
      62           2 :     return SelectFilteredProvider(
      63             :       callback: callback,
      64           2 :       notifier: read(tag: tag),
      65             :       listenWhenTheCallbackReturnsTrue: booleanCallback,
      66             :     );
      67             :   }
      68             : 
      69           2 :   WhenFilteredProvider<N, S> when<R>(
      70             :     BuildWhenCallback<S> callback, {
      71             :     String? tag,
      72             :     bool booleanCallback = false,
      73             :   }) {
      74           2 :     return WhenFilteredProvider(
      75             :       callback: callback,
      76           2 :       notifier: read(tag: tag),
      77             :     );
      78             :   }
      79             : }
      80             : 
      81             : /// create the listener for provider.select filter (StateProvider)
      82           2 : void createSelectListener<N extends StateNotifier<S>, S, R>(
      83             :   SelectFilteredProvider<N, S, R> filter,
      84             : ) {
      85           8 :   R prevValue = filter.callback(filter.notifier.state);
      86           2 :   filter.selectValue = prevValue;
      87             : 
      88           4 :   filter.listener = (newState) {
      89           8 :     final value = filter.callback(filter.notifier.state);
      90           2 :     if (filter.listenWhenTheCallbackReturnsTrue) {
      91             :       assert(
      92           2 :         value is bool,
      93             :         'The value returned by the callback must be a boolean because '
      94             :         'listenWhenTheCallbackReturnsTrue is true',
      95             :       );
      96             :     }
      97             : 
      98           2 :     filter.selectValue = value;
      99             : 
     100             :     bool allowRebuild = false;
     101           3 :     if (value is bool && filter.listenWhenTheCallbackReturnsTrue) {
     102             :       allowRebuild = value;
     103           1 :     } else if (prevValue != value) {
     104             :       allowRebuild = true;
     105             :     }
     106             : 
     107             :     // check if the value has changed
     108           2 :     if (allowRebuild && filter.reaction != null) {
     109           6 :       filter.reaction!(filter.notifier);
     110             :     }
     111             :     prevValue = value;
     112             :   };
     113             : }
     114             : 
     115             : /// create the listener for provider.when filter
     116           2 : void createWhenListener<N extends StateNotifier<S>, S>(
     117             :   WhenFilteredProvider<N, S> filter,
     118             : ) {
     119           2 :   final notifier = filter.notifier;
     120           4 :   filter.listener = (newState) {
     121             :     // rebuild the Consumer using the boolean returned by the callback
     122           6 :     final allowRebuild = filter.callback(notifier.oldState, newState);
     123             :     if (allowRebuild) {
     124           4 :       filter.reaction?.call(notifier);
     125             :     }
     126             :   };
     127             : }

Generated by: LCOV version 1.16