/
enum.dart
141 lines (132 loc) · 4.8 KB
/
enum.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of dart.core;
/// An enumerated value.
///
/// This class is implemented by all types and values
/// introduced using an `enum` declaration.
/// Non-platform classes cannot implement, extend or
/// mix in this class.
@Since("2.14")
abstract class Enum {
/// A numeric identifier for the enumerated value.
///
/// The values of a single enumeration are numbered
/// consecutively from zero to one less than the
/// number of values.
/// This is also the index of the value in the
/// enumerated type's static `values` list.
int get index;
/// The value's "name".
///
/// The name of a value is a string containing the
/// source identifier used to declare the value.
///
/// The name occurs in the [toString] of the
/// enum value, after the enum class name and a `.`.
/// It is exposed by then [EnumName.name] extension getter,
/// which is an extension to allow `enum` declarations to have
/// an element named `name` without causing a name conflict.
///
/// Given an enum declaration like
/// ```dart
/// enum MyEnum {
/// value1,
/// value2
/// }
/// ```
/// the `toString` method of that class may be implemented
/// as
/// ```dart
/// String toString() => "MyEnum.$_name";
/// ```
String get _name;
/// Compares two enum values by their [index].
///
/// A generic [Comparator] function for enum types which
/// orders enum values by their [index] value, which corresponds
/// to the source order of the enum element declarations in
/// the `enum` declaration.
@Since("2.15")
static int compareByIndex<T extends Enum>(T value1, T value2) =>
value1.index - value2.index;
/// Compares enum values by name.
///
/// The [EnumName.name] of an enum value is a string
/// representing the source name used to declare that enum value.
///
/// This [Comparator] compares two enum values by comparing their names,
/// and can be used to sort enum values by their names.
/// The comparison uses [String.compareTo], and is therefore case sensitive.
@Since("2.15")
static int compareByName<T extends Enum>(T value1, T value2) =>
value1.name.compareTo(value2.name);
}
/// Superclass of all enum class implementations.
abstract class _Enum implements Enum {
final int index;
final String _name;
const _Enum(this.index, this._name);
}
/// Access to the name of an enum value.
///
/// This method is declared as an extension method
/// instead of an instance method in order to allow
/// enum values to have the name `name`.
@Since("2.15")
extension EnumName on Enum {
/// The name of the enum value.
///
/// The name is a string containing the source identifier used
/// to declare the enum value.
///
/// For example, given a declaration like:
/// ```dart
/// enum MyEnum {
/// value1,
/// value2
/// }
/// ```
/// the result of `MyEnum.value1.name` is the string `"value1"`.
String get name => _name;
}
/// Access enum values by name.
///
/// Extensions on a collection of enum values,
/// intended for use on the `values` list of an enum type,
/// which allows looking up a value by its name.
///
/// Since enum classes are expected to be relatively small,
/// lookup of [byName] is performed by linearly iterating through the values
/// and comparing their name to the provided name.
/// If a more efficient lookup is needed, perhaps because the lookup operation
/// happens very often, consider building a map instead using [asNameMap]:
/// ```dart
/// static myEnumNameMap = MyEnum.values.asNameMap();
/// ```
/// and then use that for lookups.
@Since("2.15")
extension EnumByName<T extends Enum> on Iterable<T> {
/// Finds the enum value in this list with name [name].
///
/// Goes through this collection looking for an enum with
/// name [name], as reported by [EnumName.name].
/// Returns the first value with the given name. Such a value must be found.
T byName(String name) {
for (var value in this) {
if (value._name == name) return value;
}
throw ArgumentError.value(name, "name", "No enum value with that name");
}
/// Creates a map from the names of enum values to the values.
///
/// The collection that this method is called on is expected to have
/// enums with distinct names, like the `values` list of an enum class.
/// Only one value for each name can occur in the created map,
/// so if two or more enum values have the same name (either being the
/// same value, or being values of different enum type), at most one of
/// them will be represented in the returned map.
Map<String, T> asNameMap() =>
<String, T>{for (var value in this) value._name: value};
}