Last updated:
0 purchases
enum extendable generator
Generates code for the extension on an enum.
Overview #
Being able to add fields and methods to an enum.
Let's say we have the following enum:
enum MathOperator { plus, minus }
copied to clipboard
It would be handy to use the enum values such as instances of some regular Dart class.
For example,
final n1 = 1;
final n2 = 2.0;
MathOperator.values.forEach((operator) {
print('$n1 ${operator.symbol} $n2 = ${operator.calculate(n1, n2)}');
});
copied to clipboard
An extension on the enum will help us with it.
Extensions can give us even more.
We can get a specific enum item from the instance of a Dart class, for example in such way:
final MathOperator? mathOperator = "+".toMathOperatorFromSymbol();
copied to clipboard
We can do it with collections as well:
final List<MathOperator?> mathOperators = ['+', '*'].toMathOperatorFromSymbol();
copied to clipboard
All these extensions can be generated by this package.
Usage #
Install #
First, add build_runner and EnumExtendable to the pubspec.yaml file:
# pubspec.yaml
dependencies:
enum_extendable_annotation:
dev_dependencies:
build_runner:
enum_extendable_generator:
copied to clipboard
And install them:
# Dart
pub get
# Flutter
flutter packages get
copied to clipboard
Packages:
build_runner, the tool to run code-generators;
enum_extendable_generator, the code generator;
enum_extendable_annotation, a package containing annotations
for enum_extendable_generator.
Create a PODO (Plain Old Data Object) class and add annotations #
Next, we need to create a PODO class to describe properties of the enum.
For example,
@ExtendableEnum()
enum MathOperator { plus, minus }
@ExtendableEnumPodo()
class _MathOperatorPodo {
final String symbol;
final num Function(num, num) calculate;
_MathOperatorPodo({
required this.symbol,
required this.calculate,
});
@ExtendableEnumValues()
static final Map<MathOperator, _MathOperatorPodo> _values = {
MathOperator.plus: _MathOperatorPodo(
symbol: "+",
calculate: (n1, n2) => n1 + n2,
),
MathOperator.minus: _MathOperatorPodo(
symbol: "-",
calculate: (n1, n2) => n1 - n2,
),
};
}
copied to clipboard
There are properties of an enum item that we want
final String symbol;
final num Function(num, num) calculate;
copied to clipboard
and a PODO object instance for each enum item in the Map<MathOperator, _MathOperatorPodo> values.
Three annotations are used here:
the enum annotation - @ExtendableEnum();
the PODO class annotation - @ExtendableEnumPodo();
the values map annotation - @ExtendableEnumValues().
Run the generator #
If your package depends on Flutter:
flutter pub run build_runner build
If your package does not depend on Flutter:
dart pub run build_runner build
EnumExtendable will need us to both import the annotation
and use the part keyword on the top of your files.
So, a file that wants to use EnumExtendable should start with:
import 'package:enum_extendable_annotation/enum_extendable_annotation.dart';
part 'example.enum_extendable.g.dart';
copied to clipboard
Note: If there is any collection field in the PODO object, one more import needs to be added (to compare collections correctly):
import 'package:collection/collection.dart';
copied to clipboard
Features #
Extensions #
Let's take the MathOperator enum as an example to explore available
extensions.
@ExtendableEnum()
enum MathOperator { plus, minus }
@ExtendableEnumPodo()
class _MathOperatorPodo {
final String symbol;
final num Function(num, num) calculate;
@ExtendableEnumValues()
static final Map<MathOperator, _MathOperatorPodo> _values = {
...
};
copied to clipboard
1. Extension on enum
This package generates an extension on enum for all fields of the PODO class.
extension MathOperatorExt on MathOperator {
String get symbol {
_checkMathOperatorValues();
return _MathOperatorPodo._values[this]!.symbol;
}
num Function(num, num) get calculate {
_checkMathOperatorValues();
return _MathOperatorPodo._values[this]!.calculate;
}
}
copied to clipboard
2. Extensions on classes of the PODO fields types
If we need to get a specific enum item by the value of some field of the PODO class
final MathOperator? mathOperator = "+".toMathOperatorFromSymbol();
copied to clipboard
then we can use the generated class extension:
extension MathOperatorStringExt on String {
MathOperator? toMathOperatorBySymbol({MathOperator? defaultValue}) {
_checkMathOperatorValues();
for (MathOperator element in _MathOperatorPodo._values.keys) {
if (_MathOperatorPodo._values[element]!.symbol == this) {
return element;
}
}
return defaultValue;
}
}
copied to clipboard
3. Extensions on Iterable
Finally, similar extensions will be generated for Iterable.
extension MathOperatorStringIterableExt on Iterable<String> {
List<MathOperator?> toMathOperatorBySymbol({MathOperator? defaultValue}) {
_checkMathOperatorValues();
return List<MathOperator?>.of(
map((e) => e.toMathOperatorBySymbol(defaultValue: defaultValue))
.toList());
}
List<MathOperator> toNotNullMathOperatorBySymbol(
MathOperator defaultValue,
) {
_checkMathOperatorValues();
return List<MathOperator>.of(map((e) =>
e.toMathOperatorBySymbol(defaultValue: defaultValue) ??
defaultValue).toList());
}
}
copied to clipboard
Such extensions allow us to map an iterable to a list of the enum items:
final List<MathOperator?> mathOperators = ['+', '-'].toMathOperatorFromSymbol();
copied to clipboard
Annotations #
ExtendableEnum
The enum should be annotated with ExtendableEnum.
It's a mandatory annotation.
ExtendableEnumPodo
Use 'ExtendableEnumPodo' to annotate the PODO class of your enum.'
It's the second mandatory annotation.
ExtendableEnumValues
The map of values (PODO instances by enum values) should be annotated with ExtendableEnumValues.
This annotation can be omitted, if the name of this field is values.
There is one parameter bool checkCompleteness. If the value of this parameter is true an assert statement is generated to make sure that all enum items are in the values map. It can be useful when a new item is added into the enum.
The default value of checkCompleteness is true.
ExtendableEnumField
Any field of the PODO class can be annotated with ExtendableEnumField. This annotation is optional and can be used to determinate extensions nomenclature. It has two parameters:
bool enumExtension - set false if you don't want to generate a method for this field at the extension on enum.
The default value is true.
bool classExtension - set false if you don't want to generate methods for a class (and Iterable of this class) of this field.
The default value is true.
Live Templates #
Find the live template for Android studio here
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.