GithubHelp home page GithubHelp logo

prazedotid / super_enum Goto Github PK

View Code? Open in Web Editor NEW

This project forked from xsahil03x/super_enum

0.0 0.0 0.0 198 KB

Create super-powered dart enums similar to sealed classes in Kotlin

Home Page: https://pub.dev/packages/super_enum

License: MIT License

Kotlin 0.56% Swift 0.68% Objective-C 0.06% Dart 96.99% HTML 0.30% Shell 1.41%

super_enum's Introduction

Dart CI codecov Version Version

Super-powered enums similar to sealed classes in Kotlin

Migration From v0.3.0 to v0.4.0

  • DataField signature has been changed.
    • DataField(String,Type) should be replaced with DataField<Type>(String)
    • Should specify generic data types (eg: List, Map) in the following manner- DataField<List<Foo>>('foos')

Installation

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

dependencies:
  super_enum: ^[version]

dev_dependencies:
  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";

@superEnum
enum _Result {
  @generic
  @Data(fields: [
    DataField<Generic>('data'),
    DataField<String>('message'),
  ])
  Success,

  @object
  Error,
}

@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 you want some DataField to be optional, set required param to false.
  • 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.

NOTE: If you want to use existing classes directly without having them auto-generated and wrapped use @UseClass().

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

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

  factory Result.success({@required T data, @required String message}) =
      Success<T>.create;

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

  final _Result _type;

//ignore: missing_return
  R when<R>(
      {@required R Function(Success<T>) success,
      @required R Function() 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();
    }
  }

//ignore: missing_return
  Future<R> asyncWhen<R>(
      {@required FutureOr<R> Function(Success<T>) success,
      @required FutureOr<R> Function() 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();
    }
  }

  R whenOrElse<R>(
      {R Function(Success<T>) success,
      R Function() error,
      @required R Function(Result<T>) 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();
    }
    return orElse(this);
  }

  Future<R> asyncWhenOrElse<R>(
      {FutureOr<R> Function(Success<T>) success,
      FutureOr<R> Function() error,
      @required FutureOr<R> Function(Result<T>) 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();
    }
    return orElse(this);
  }

//ignore: missing_return
  Future<void> whenPartial(
      {FutureOr<void> Function(Success<T>) success,
      FutureOr<void> Function() 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();
    }
  }

  @override
  List<Object> get props => const [];
}

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

  factory Success.create({@required T data, @required String message}) =
      _SuccessImpl<T>;

  final T data;

  final String message;

  Success<T> copyWith({T data, String message});
}

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

  @override
  final T data;

  @override
  final String message;

  @override
  _SuccessImpl<T> copyWith(
          {Object data = superEnum, Object message = superEnum}) =>
      _SuccessImpl(
        data: data == superEnum ? this.data : data as T,
        message: message == superEnum ? this.message : message as String,
      );
  @override
  String toString() => 'Success(data: ${this.data}, message: ${this.message})';
  @override
  List<Object> get props => [data, message];
}

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

  factory Error.create() = _ErrorImpl<T>;
}

@immutable
class _ErrorImpl<T> extends Error<T> {
  const _ErrorImpl() : super();

  @override
  String toString() => 'Error()';
}

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
_resultController.add(Result.success(
              data: 333,
              message: 'Success',
            ));

// Adding an error state to the stream controller
_resultController.add(Result.error());

// Listening to all the possible Result states
_resultController.stream.listen((result) {
      result.when(
        onSuccess: (data) => print(data.message), // Success
        onError: () => print('Error Occurred'), // Error Occurred
      );
    });

UseClass Example

A sample UseClass() example.

class MySuccess {
  MySuccess(this.fieldA);

  final String fieldA;
}

class MyError {
  MyError(this.fieldA, this.fieldB);

  final String fieldA;
  final int fieldB;
}

@superEnum
enum _ResultUnion {
  @UseClass(MySuccess)
  Success,

  @UseClass(MyError)
  Error,
}

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.

super_enum's People

Contributors

xsahil03x avatar astralstriker avatar passsy avatar prazedotid avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.