Skip to content

Instantly share code, notes, and snippets.

@PlugFox
Last active May 10, 2024 22:55
Show Gist options
  • Save PlugFox/d96a5f7a20722079697edfa95cccc707 to your computer and use it in GitHub Desktop.
Save PlugFox/d96a5f7a20722079697edfa95cccc707 to your computer and use it in GitHub Desktop.
Enum utils
import 'package:benchmark_harness/benchmark_harness.dart';
void main() {
final letter = Example.values[25];
final simple = Simple(letter).measure();
final cache = Cache(letter).measure();
print('$simple / $cache = ${simple / cache}'); // 4.074025631823892
}
enum Example {
a,
b,
c,
d,
e,
f,
g,
h,
i,
j,
k,
l,
m,
n,
o,
p,
q,
r,
s,
t,
u,
v,
w,
x,
y,
z
}
class Simple extends BenchmarkBase {
Simple([this.letter = Example.g])
: name = letter.name,
super('Simple');
final Example letter;
final String name;
@override
void run() {
final result = Example.values.firstWhere((element) => element.name == name);
if (result != letter) throw Exception('Error');
}
}
class Cache extends BenchmarkBase {
Cache([this.letter = Example.g])
: name = letter.name,
super('Cache');
final Example letter;
final String name;
@override
void run() {
final result = EnumUtil.search(Example.values, name);
if (result != letter) throw Exception('Error');
}
}
abstract final class EnumUtil {
static final Map<int, Map<String, Enum>> _$searchCache = {};
static Never _$searchNotFound() => throw Exception('Not found');
static T search<T extends Enum>(
Iterable<T> values,
Object? /* String | int */ value, {
T Function()? fallback,
}) {
if (value is String) {
final cache = _$searchCache.putIfAbsent(
values.hashCode, () => {for (final e in values) e.name: e});
if (cache[value] case T result) return result;
} else if (value is int) {
try {
return values.elementAt(value);
} on RangeError {/* ignore */}
}
return fallback?.call() ?? _$searchNotFound();
}
}
void main() {
print(EnumUtil.search(Example.values, 'a'));
print(EnumUtil.search(Example.values, 1));
print(EnumUtil.search(Example.values, 'z', fallback: () => Example.c));
}
enum Example { a, b, c }
abstract final class EnumUtil {
static final Map<int, Map<String, Enum>> _$searchCache = {};
static Never _$searchNotFound() => throw Exception('Not found');
static T search<T extends Enum>(
Iterable<T> values,
Object? /* String | int */ value, {
T Function()? fallback,
}) {
if (value is String) {
final cache = _$searchCache.putIfAbsent(
values.hashCode, () => {for (final e in values) e.name: e});
if (cache[value] case T e) return e;
} else if (value is int) {
try {
return values.elementAt(value);
} on RangeError {/* ignore */}
}
return fallback?.call() ?? _$searchNotFound();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment