super_enum 0.3.0

  • Readme
  • Changelog
  • Example
  • Installing
  • 93

Dart CI codecov Version Version

Super-powered enums similar to sealed classes in Kotlin

Installation #

Add the following to you pubspec.yaml and replace [version] with the latest version:

  super_enum: ^[version]

  super_enum_generator: ^[version]
  build_runner: ^1.7.1 // Any latest version which works with your current Dart or Flutter SDK

Example #

A Super Enum can be easily generated by annotating a private enum with @superEnum

import 'package:super_enum/super_enum.dart';

part "result.g.dart";

enum _Result {
  @Data(fields: [
    DataField('data', Generic),
    DataField('message', String),


@Data() marks an enum value to be treated as a Data class.

  • One should supply a list of possible fields inside the annotation.
  • If you don't want to add fields, use @object annotation instead.
  • Fields are supplied in the form of DataField objects.
  • Each DataField must contain the name and the type of the field.
  • If the field type needs to be generic use Generic type and annotate the enum value with @generic annotation.

@object marks an enum value to be treated as an object.

Run the build_runner command to generate the filename.g.dart part file.

 # Dart SDK: $pub run build_runner build
 # Flutter SDK: $flutter pub run build_runner build

Generated file #

abstract class Result<T> extends Equatable {
  const Result(this._type);

  factory Result.success({@required T data, @required String message}) =

  factory Result.error() = Error<T>;

  final _Result _type;

//ignore: missing_return
  FutureOr<R> when<R>(
      {@required FutureOr<R> Function(Success) success,
      @required FutureOr<R> Function(Error) error}) {
    assert(() {
      if (success == null || error == null)
        throw 'check for all possible cases';
      return true;
    switch (this._type) {
      case _Result.Success:
        return success(this as Success);
      case _Result.Error:
        return error(this as Error);

  FutureOr<R> whenOrElse<R>(
      {FutureOr<R> Function(Success) success,
      FutureOr<R> Function(Error) error,
      @required FutureOr<R> Function(Result) orElse}) {
    assert(() {
      if (orElse == null) throw 'Missing orElse case';
      return true;
    switch (this._type) {
      case _Result.Success:
        if (success == null) break;
        return success(this as Success);
      case _Result.Error:
        if (error == null) break;
        return error(this as Error);
    return orElse(this);

  FutureOr<void> whenPartial(
      {FutureOr<void> Function(Success) success,
      FutureOr<void> Function(Error) error}) {
    assert(() {
      if (success == null && error == null) throw 'provide at least one branch';
      return true;
    switch (this._type) {
      case _Result.Success:
        if (success == null) break;
        return success(this as Success);
      case _Result.Error:
        if (error == null) break;
        return error(this as Error);

  List get props => const [];

class Success<T> extends Result<T> {
  const Success({@required, @required this.message})
      : super(_Result.Success);

  final T data;

  final String message;

  String toString() => 'Success(data:${},message:${this.message})';
  List get props => [data, message];

class Error<T> extends Result<T> {
  const Error._() : super(_Result.Error);

  factory Error() {
    _instance ??= Error._();
    return _instance;

  static Error _instance;

Usage #

Below is just one of the use-case of Super Enums. It can be used wherever you want to manage state.

// Creating an StreamController of type Result<int>
final _resultController = StreamController<Result<int>>();

// Adding a success state to the stream controller
              data: 333,
              message: 'Success',

// Adding an error state to the stream controller

// Listening to all the possible Result states {
        onSuccess: (data) => print(data.message), // Success
        onError: (_) => print('Error Occurred'), // Error Occurred

Getting Started #

This project is a starting point for a Dart package, a library module containing code that can be shared easily across multiple Flutter or Dart projects.

For help getting started with Flutter, view our online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.


1. Added two new 'whenX' methods.
    - whenOrElse
    - whenPartial

2. Bug fixes and improvements.


1. Make object classes singleton.

2. Make Data classes Equatable 
    * '=='
    * 'hashCode'
    * 'toString'


Added a proper example.


Fix homepage link.


Initial Release.


import 'dart:convert';

import 'package:meta/meta.dart';
import 'package:http/http.dart' as http;
import 'package:super_enum/super_enum.dart';
import 'dart:io';

import 'movies.dart';

part 'main.g.dart';

enum _MoviesResponse {
  @Data(fields: [DataField('movies', Movies)])
  @Data(fields: [DataField('exception', Exception)])

class MoviesFetcher {
  http.Client client = http.Client();
  final _baseUrl = "";

  final String apiKey;

  MoviesFetcher({@required this.apiKey});

  Future<MoviesResponse> fetchMovies() async {
    try {
      final response = await client.get('$_baseUrl/popular?api_key=$apiKey');
      if (response.statusCode == 200) {
        final movies = Movies.fromJson(json.decode(response.body));
        return MoviesResponse.success(movies: movies);
      } else {
        return MoviesResponse.unauthorized();
    } on SocketException {
      return MoviesResponse.noNetwork();
    } catch (e) {
      return MoviesResponse.unexpectedException(exception: e);

void main() async {
  final _moviesFetcher = MoviesFetcher(
    apiKey: '9c9576f8c2e86949a3220fcc32ae2fb6',

  final _moviesResponse = await _moviesFetcher.fetchMovies();

    success: (data) => print('Total Movies: ${data.movies.totalPages}'),
    unauthorized: (_) => print('Invalid ApiKey'),
    noNetwork: (_) => print(
      'No Internet, Please check your internet connection',
    unexpectedException: (error) => print(error.exception),

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:

  super_enum: ^0.3.0

2. Install it

You can install packages from the command line:

with pub:

$ pub get

with Flutter:

$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:

import 'package:super_enum/super_enum.dart';
Describes how popular the package is relative to other packages. [more]
Code health derived from static analysis. [more]
Reflects how tidy and up-to-date the package is. [more]
Weighted score of the above. [more]
Learn more about scoring.

We analyzed this package on Jan 19, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.0
  • pana: 0.13.4

Health issues and suggestions

Document public APIs. (-1 points)

14 out of 14 API elements have no dartdoc comment.Providing good documentation for libraries, classes, functions, and other API elements improves code readability and helps developers find and use your API.


Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
equatable ^1.0.0 1.0.2
meta ^1.1.7 1.1.8
Transitive dependencies
collection 1.14.12
Dev dependencies
build_runner ^1.7.1
http ^0.12.0+2