Class: Literal::Enum
- Inherits:
-
Object
show all
- Extended by:
- Enumerable, Properties
- Defined in:
- lib/literal/enum.rb
Constant Summary
Constants included
from Types
Types::CallableType, Types::LambdaType, Types::NilableBooleanType, Types::NilableCallableType, Types::NilableJSONDataType, Types::NilableLambdaType, Types::NilableProcableType, Types::ProcableType
Class Attribute Summary collapse
Instance Attribute Summary collapse
Class Method Summary
collapse
-
.[](value) ⇒ Object
(also: cast)
-
.__after_defined__ ⇒ Object
-
._load(data) ⇒ Object
-
.at_position(n) ⇒ Object
-
.coerce(value) ⇒ Object
-
.const_added(name) ⇒ Object
-
.each ⇒ Object
-
.each_value ⇒ Object
-
.fetch ⇒ Object
-
.find_by(**kwargs) ⇒ Object
-
.index(name, type, unique: true, &block) ⇒ Object
-
.inherited(subclass) ⇒ Object
-
.names ⇒ Object
-
.new(*args, **kwargs, &block) ⇒ Object
-
.position_of(member) ⇒ Object
-
.prop(name, type, kind = :keyword, reader: :public, predicate: false, default: nil, description: nil) ⇒ Object
-
.to_h ⇒ Object
-
.to_proc ⇒ Object
-
.values ⇒ Object
-
.where(**kwargs) ⇒ Object
Instance Method Summary
collapse
Methods included from Properties
extended, initialize, literal_properties, prop, prop?
Methods included from Types
#_Any, #_Any?, #_Array, #_Array?, #_Boolean, #_Boolean?, #_Callable, #_Callable?, #_Class, #_Class?, #_Constraint, #_Constraint?, #_Date, #_Date?, #_Deferred, #_Deferred?, #_Descendant, #_Descendant?, #_Enumerable, #_Enumerable?, #_Falsy, #_Float, #_Float?, #_Frozen, #_Frozen?, #_Hash, #_Hash?, #_Integer, #_Integer?, #_Interface, #_Interface?, #_Intersection, #_Intersection?, #_JSONData, #_JSONData?, #_Kind, #_Lambda, #_Lambda?, #_Map, #_Map?, #_Never, #_Nilable, #_Not, #_Pattern, #_Predicate, #_Procable, #_Procable?, #_Range, #_Range?, #_SameObject, #_SameObject?, #_Set, #_Set?, #_String, #_String?, #_Symbol, #_Symbol?, #_TaggedUnion, #_TaggedUnion?, #_Time, #_Time?, #_Truthy, #_Tuple, #_Tuple?, #_Union, #_Union?, #_Void
Class Attribute Details
Returns the value of attribute members.
9
10
11
|
# File 'lib/literal/enum.rb', line 9
def members
@members
end
|
Instance Attribute Details
#__position__ ⇒ Object
Returns the value of attribute position.
250
251
252
|
# File 'lib/literal/enum.rb', line 250
def __position__
@__position__
end
|
Class Method Details
.[](value) ⇒ Object
Also known as:
cast
157
158
159
|
# File 'lib/literal/enum.rb', line 157
def [](value)
@values[value]
end
|
.__after_defined__ ⇒ Object
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
142
143
144
145
146
147
|
# File 'lib/literal/enum.rb', line 116
def __after_defined__
raise ArgumentError if frozen?
if RUBY_VERSION < "3.2"
constants(false).each { |name| const_added(name) }
end
@indexes_definitions.each do |name, (type, unique, block)|
index = @members.group_by(&block).freeze
index.each do |key, values|
unless type === key
raise Literal::TypeError.new(
context: Literal::TypeError::Context.new(
expected: type,
actual: key,
)
)
end
if unique && values.size > 1
raise ArgumentError.new("The index #{name} is not unique.")
end
end
@indexes[name] = index
end
@values.freeze
@members.freeze
freeze
end
|
._load(data) ⇒ Object
80
81
82
|
# File 'lib/literal/enum.rb', line 80
def _load(data)
self[Marshal.load(data)]
end
|
.at_position(n) ⇒ Object
41
42
43
|
# File 'lib/literal/enum.rb', line 41
def at_position(n)
@members[n]
end
|
.coerce(value) ⇒ Object
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
# File 'lib/literal/enum.rb', line 167
def coerce(value)
case value
when self
value
when Symbol
self[value] || begin
const_get(value)
rescue NameError
raise ArgumentError.new(
"Can't coerce #{value.inspect} into a #{inspect}."
)
end
else
self[value] || raise(
ArgumentError.new(
"Can't coerce #{value.inspect} into a #{inspect}."
)
)
end
end
|
.const_added(name) ⇒ Object
84
85
86
87
88
89
90
91
92
93
94
|
# File 'lib/literal/enum.rb', line 84
def const_added(name)
raise ArgumentError if frozen?
object = const_get(name)
if self === object
@names[object] = name
predicate_name = name.to_s.gsub(/(?<=[A-Z])(?=[A-Z][a-z])|(?<=[a-z\d])(?=[A-Z])/, "_").downcase
define_method("#{predicate_name}?") { self == object }
object.freeze
end
end
|
149
150
151
|
# File 'lib/literal/enum.rb', line 149
def each
@members.each { |member| yield(member) }
end
|
.each_value ⇒ Object
153
154
155
|
# File 'lib/literal/enum.rb', line 153
def each_value(&)
@values.each_key(&)
end
|
163
164
165
|
# File 'lib/literal/enum.rb', line 163
def fetch(...)
@values.fetch(...)
end
|
.find_by(**kwargs) ⇒ Object
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
# File 'lib/literal/enum.rb', line 63
def find_by(**kwargs)
unless kwargs.length == 1
raise ArgumentError.new("You can only specify one index when using `where`.")
end
key, value = kwargs.first
unless @indexes_definitions.fetch(key)[1]
raise ArgumentError.new("You can only use `find_by` on unique indexes.")
end
type = @indexes_definitions.fetch(key)[0]
Literal.check(value, type)
@indexes.fetch(key)[value]&.first
end
|
.index(name, type, unique: true, &block) ⇒ Object
45
46
47
|
# File 'lib/literal/enum.rb', line 45
def index(name, type, unique: true, &block)
@indexes_definitions[name] = [type, unique, block || name.to_proc]
end
|
.inherited(subclass) ⇒ Object
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
# File 'lib/literal/enum.rb', line 18
def inherited(subclass)
subclass.instance_exec do
@values = {}
@members = []
@indexes_definitions = {}
@indexes = {}
@names = {}
end
if subclass.name && RUBY_ENGINE != "truffleruby"
TracePoint.trace(:end) do |tp|
if tp.self == subclass
tp.self.__after_defined__
tp.disable
end
end
end
end
|
12
|
# File 'lib/literal/enum.rb', line 12
def names = @names
|
.new(*args, **kwargs, &block) ⇒ Object
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
# File 'lib/literal/enum.rb', line 96
def new(*args, **kwargs, &block)
raise ArgumentError if frozen?
new_object = super(*args, **kwargs, &nil)
if @values.key?(new_object.value)
raise ArgumentError.new("The value #{new_object.value} is already used by #{@values[new_object.value].name}.")
end
@values[new_object.value] = new_object
new_object.instance_variable_set(:@__position__, @members.length)
@members << new_object
new_object.instance_exec(&block) if block
new_object
end
|
.position_of(member) ⇒ Object
37
38
39
|
# File 'lib/literal/enum.rb', line 37
def position_of(member)
coerce(member).__position__
end
|
.prop(name, type, kind = :keyword, reader: :public, predicate: false, default: nil, description: nil) ⇒ Object
14
15
16
|
# File 'lib/literal/enum.rb', line 14
def prop(name, type, kind = :keyword, reader: :public, predicate: false, default: nil, description: nil)
super(name, type, kind, reader:, writer: false, predicate:, default:, description:)
end
|
192
193
194
195
196
197
198
|
# File 'lib/literal/enum.rb', line 192
def to_h(&)
if block_given?
@members.to_h(&)
else
@members.to_h { |it| [it, it.value] }
end
end
|
188
189
190
|
# File 'lib/literal/enum.rb', line 188
def to_proc
method(:coerce).to_proc
end
|
11
|
# File 'lib/literal/enum.rb', line 11
def values = @values.keys
|
.where(**kwargs) ⇒ Object
49
50
51
52
53
54
55
56
57
58
59
60
61
|
# File 'lib/literal/enum.rb', line 49
def where(**kwargs)
unless kwargs.length == 1
raise ArgumentError.new("You can only specify one index when using `where`.")
end
key, value = kwargs.first
types = @indexes_definitions.fetch(key)
type = types.first
Literal.check(value, type)
@indexes.fetch(key)[value]
end
|
Instance Method Details
#<=>(other) ⇒ Object
229
230
231
232
233
234
235
236
|
# File 'lib/literal/enum.rb', line 229
def <=>(other)
case other
when self.class
@__position__ <=> other.__position__
else
raise ArgumentError.new("Can't compare instances of #{other.class} to instances of #{self.class}")
end
end
|
#_dump(level) ⇒ Object
225
226
227
|
# File 'lib/literal/enum.rb', line 225
def _dump(level)
Marshal.dump(@value)
end
|
#deconstruct ⇒ Object
216
217
218
|
# File 'lib/literal/enum.rb', line 216
def deconstruct
[@value]
end
|
#deconstruct_keys(keys) ⇒ Object
220
221
222
223
|
# File 'lib/literal/enum.rb', line 220
def deconstruct_keys(keys)
h = to_h
keys ? h.slice(*keys) : h
end
|
#name ⇒ Object
Also known as:
inspect
201
202
203
204
|
# File 'lib/literal/enum.rb', line 201
def name
klass = self.class
"#{klass.name}::#{klass.names[self]}"
end
|
242
243
244
245
246
247
248
|
# File 'lib/literal/enum.rb', line 242
def pred
if @__position__ <= 0
nil
else
self.class.members[@__position__ - 1]
end
end
|
238
239
240
|
# File 'lib/literal/enum.rb', line 238
def succ
self.class.members[@__position__ + 1]
end
|
212
213
214
|
# File 'lib/literal/enum.rb', line 212
def to_s
to_sym.to_s
end
|
208
209
210
|
# File 'lib/literal/enum.rb', line 208
def to_sym
self.class.names[self]
end
|