Since Dart 2.17, we can declare enums with members.
/// {@template status}
/// Status enumeration
/// {@endtemplate}
enum Status with Comparable<Status> {
/// Loading
loading('Loading'),
/// Idle
idle('Idle'),
/// Error
error('Error');
/// {@macro status}
const Status(this.value);
/// Creates a new instance of [Status] from a given string.
static Status fromValue(Object? value, {Status? fallback}) {
final status = value?.toString().split('.').last.trim().toLowerCase();
switch (status) {
case 'loading':
return loading;
case 'idle':
return idle;
case 'error':
return error;
default:
return fallback ?? (throw ArgumentError.value(value));
}
}
/// Value of the enum
final String value;
/// Pattern matching
T map<T>({
required T Function() loading,
required T Function() idle,
required T Function() error,
}) {
switch (this) {
case Status.loading:
return loading();
case Status.idle:
return idle();
case Status.error:
return error();
}
}
/// Pattern matching
T maybeMap<T>({
required T Function() orElse,
T Function()? loading,
T Function()? idle,
T Function()? error,
}) =>
map<T>(
loading: loading ?? orElse,
idle: idle ?? orElse,
error: error ?? orElse,
);
/// Pattern matching
T? maybeMapOrNull<T>({
T Function()? loading,
T Function()? idle,
T Function()? error,
}) =>
maybeMap<T?>(
orElse: () => null,
loading: loading,
idle: idle,
error: error,
);
@override
int compareTo(Status other) => index.compareTo(other.index);
@override
String toString() => value;
}