A powerful Dart package that generates convenient extensions for BLoC/Cubit state classes, offering pattern matching and logging capabilities through simple annotations. Now supports both traditional and inline state class definitions!
- match: Complete state pattern matching requiring all cases to be handled
- matchSome: Partial pattern matching with default case handling
- Compile-time type safety
- Built-in state logging functionality
- Debug-friendly state information
- Support for both traditional and inline state class definitions
- Automatic state class detection from Bloc/Cubit generic types
- Works with both Bloc and Cubit patterns
-
Add
bloc_state_gen
to yourpubspec.yaml
:dependencies: bloc_state_gen: ^latest_version dev_dependencies: build_runner: ^latest_version
-
Update your main cubit class to include the generated file and add annotation
@BlocStateGen()
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:bloc_state_gen/bloc_state_gen.dart'; part 'search_state.dart'; part 'search_cubit.s.dart'; @BlocStateGen() class SearchCubit extends Cubit<SearchState> { SearchCubit() : super(const SearchInitial()); }
-
Run the code generator:
flutter pub run build_runner build
-
Ignore generated
.s.dart
files in version control by adding the following to your.gitignore
:# Ignore generated files *.s.dart
-
Run the code generator:
flutter pub run build_runner build
Requires handling all possible states:
Widget buildStateWidget(SearchState state) {
return state.match(
searchInitial: () => const StartSearch(),
searching: (query) => const CircularProgressIndicator(),
searchResults: (query, results) => DisplayList(items: results),
noResults: (query) => NoResultsWidget(query: query),
searchError: (message, query) => ErrorMessage(message: message),
);
}
Handle specific states with a default case:
String getDisplayText(SearchState state) {
return state.matchSome(
searchResults: (query, results) => 'Found ${results.length} results for: $query',
searchError: (message, query) => 'Error${query != null ? " for $query" : ""}: $message',
orElse: () => 'Idle...',
);
}
Print state information for debugging:
void debugState(CounterState state) {
print(state.log()); // Outputs formatted state information
}
You can selectively enable/disable features using the @BlocStateGen
annotation:
@BlocStateGen(
match: true, // Enable complete pattern matching
matchSome: true, // Enable partial pattern matching
log: true, // Enable logging functionality
)
class SearchCubit extends Cubit<SearchState> {
SearchCubit() : super(const SearchInitial());
}
-
Complete Pattern Matching
- Use
match
when you need to handle all possible states - Ensures no state is accidentally forgotten
- Provides compile-time safety
- Use
-
Partial Pattern Matching
- Use
matchSome
when you only need to handle specific states - Always provide a meaningful
orElse
case - Useful for selective state handling
- Use
-
Logging
- Enable logging during development for better debugging
- Use in conjunction with Flutter's debug mode:
if (kDebugMode) {
print(state.log());
}
For a complete working example, check out our example project demonstrating:
- State class definition
- Extension generation
- Usage of all three core features
- Integration with Flutter UI
This project is licensed under the MIT License - see the LICENSE file for details.