literal 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/literal/enum.rb +3 -4
- data/lib/literal/properties/schema.rb +1 -1
- data/lib/literal/properties.rb +2 -2
- data/lib/literal/rails/enum_type.rb +4 -0
- data/lib/literal/types/array_type.rb +1 -0
- data/lib/literal/types/class_type.rb +1 -0
- data/lib/literal/types/constraint_type.rb +1 -0
- data/lib/literal/types/descendant_type.rb +1 -0
- data/lib/literal/types/enumerable_type.rb +1 -0
- data/lib/literal/types/frozen_type.rb +1 -0
- data/lib/literal/types/hash_type.rb +1 -0
- data/lib/literal/types/interface_type.rb +1 -0
- data/lib/literal/types/intersection_type.rb +1 -0
- data/lib/literal/types/map_type.rb +1 -0
- data/lib/literal/types/nilable_type.rb +1 -0
- data/lib/literal/types/not_type.rb +1 -0
- data/lib/literal/types/range_type.rb +1 -0
- data/lib/literal/types/set_type.rb +1 -0
- data/lib/literal/types/tuple_type.rb +1 -0
- data/lib/literal/types/union_type.rb +46 -25
- data/lib/literal/types.rb +140 -63
- data/lib/literal/version.rb +1 -1
- data/lib/literal.rb +25 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98bc237de806f82733e8c812bccc840c5451183afd22f369ecffc6720c3b88ba
|
4
|
+
data.tar.gz: b340a2c25c5d23d033a83dbf3ab1483a9b071424f343f0edf5c104bee83402c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17b16bdea93b6dff73b9fdcbdd269053648e996f3e2b5d6773933710281b756a50eb93684d727b46711aef990858985111f9d59d80250d20a3f71963767032ca
|
7
|
+
data.tar.gz: 67647cf3e25cdbdbdb12638081a7cbd40b5bee6771d9be54ca4100646740a97989259f24242b60064c41b016c7687d91a3969632d2195a0715c6015bede8e839
|
data/lib/literal/enum.rb
CHANGED
@@ -24,7 +24,7 @@ class Literal::Enum
|
|
24
24
|
@names = {}
|
25
25
|
end
|
26
26
|
|
27
|
-
if RUBY_ENGINE != "truffleruby"
|
27
|
+
if subclass.name && RUBY_ENGINE != "truffleruby"
|
28
28
|
TracePoint.trace(:end) do |tp|
|
29
29
|
if tp.self == subclass
|
30
30
|
tp.self.__after_defined__
|
@@ -71,9 +71,8 @@ class Literal::Enum
|
|
71
71
|
raise ArgumentError.new("You can only use `find_by` on unique indexes.")
|
72
72
|
end
|
73
73
|
|
74
|
-
|
75
|
-
|
76
|
-
end
|
74
|
+
type = @indexes_definitions.fetch(key)[0]
|
75
|
+
Literal.check(actual: value, expected: type)
|
77
76
|
|
78
77
|
@indexes.fetch(key)[value]&.first
|
79
78
|
end
|
@@ -102,7 +102,7 @@ class Literal::Properties::Schema
|
|
102
102
|
i, n = 0, sorted_properties.size
|
103
103
|
while i < n
|
104
104
|
property = sorted_properties[i]
|
105
|
-
buffer << "
|
105
|
+
buffer << " @#{property.name.name} == other.instance_variable_get(:@#{property.name.name})"
|
106
106
|
buffer << " &&\n " if i < n - 1
|
107
107
|
i += 1
|
108
108
|
end
|
data/lib/literal/properties.rb
CHANGED
@@ -30,7 +30,7 @@ module Literal::Properties
|
|
30
30
|
end
|
31
31
|
|
32
32
|
unless Literal::Property::VISIBILITY_OPTIONS.include?(predicate)
|
33
|
-
|
33
|
+
raise Literal::ArgumentError.new("The predicate must be one of #{Literal::Property::VISIBILITY_OPTIONS.map(&:inspect).join(', ')}.")
|
34
34
|
end
|
35
35
|
|
36
36
|
if reader && :class == name
|
@@ -90,7 +90,7 @@ module Literal::Properties
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def to_h
|
93
|
-
|
93
|
+
{}
|
94
94
|
end
|
95
95
|
|
96
96
|
set_temporary_name "Literal::Properties(Extension)" if respond_to?(:set_temporary_name)
|
@@ -3,23 +3,43 @@
|
|
3
3
|
class Literal::Types::UnionType
|
4
4
|
include Enumerable
|
5
5
|
|
6
|
-
def initialize(*
|
7
|
-
raise Literal::ArgumentError.new("_Union type must have at least one type.") if
|
6
|
+
def initialize(*queue)
|
7
|
+
raise Literal::ArgumentError.new("_Union type must have at least one type.") if queue.size < 1
|
8
|
+
types = []
|
9
|
+
primitives = Set[]
|
10
|
+
|
11
|
+
while queue.length > 0
|
12
|
+
type = queue.shift
|
13
|
+
case type
|
14
|
+
when Literal::Types::UnionType
|
15
|
+
queue.concat(type.types, type.primitives.to_a)
|
16
|
+
when Array, Hash, String, Symbol, Integer, Float, Complex, Rational, true, false, nil
|
17
|
+
primitives << type
|
18
|
+
else
|
19
|
+
types << type
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
types.uniq!
|
24
|
+
@types = types
|
25
|
+
@primitives = primitives
|
8
26
|
|
9
|
-
@types = []
|
10
|
-
load_types(types)
|
11
|
-
@types.uniq!
|
12
27
|
@types.freeze
|
28
|
+
@primitives.freeze
|
29
|
+
freeze
|
13
30
|
end
|
14
31
|
|
15
|
-
attr_reader :types
|
32
|
+
attr_reader :types, :primitives
|
16
33
|
|
17
34
|
def inspect
|
18
35
|
"_Union(#{@types.inspect})"
|
19
36
|
end
|
20
37
|
|
21
38
|
def ===(value)
|
39
|
+
return true if @primitives.include?(value)
|
40
|
+
|
22
41
|
types = @types
|
42
|
+
|
23
43
|
i, len = 0, types.size
|
24
44
|
while i < len
|
25
45
|
return true if types[i] === value
|
@@ -28,48 +48,49 @@ class Literal::Types::UnionType
|
|
28
48
|
end
|
29
49
|
|
30
50
|
def each(&)
|
51
|
+
@primitives.each(&)
|
31
52
|
@types.each(&)
|
32
53
|
end
|
33
54
|
|
34
55
|
def deconstruct
|
35
|
-
|
56
|
+
to_a
|
36
57
|
end
|
37
58
|
|
38
59
|
def [](key)
|
39
|
-
if @types.include?(key)
|
60
|
+
if @primitives.include?(key) || @types.include?(key)
|
40
61
|
key
|
41
|
-
else
|
42
|
-
raise ArgumentError.new("#{key} not in #{inspect}")
|
43
62
|
end
|
44
63
|
end
|
45
64
|
|
65
|
+
def fetch(key)
|
66
|
+
self[key] or raise KeyError.new("Key not found: #{key.inspect}")
|
67
|
+
end
|
68
|
+
|
46
69
|
def record_literal_type_errors(ctx)
|
47
|
-
|
70
|
+
each do |type|
|
48
71
|
ctx.add_child(label: type.inspect, expected: type, actual: ctx.actual)
|
49
72
|
end
|
73
|
+
|
50
74
|
ctx.children.clear if ctx.children.none? { |c| c.children.any? }
|
51
75
|
end
|
52
76
|
|
53
77
|
def >=(other)
|
78
|
+
types = @types
|
79
|
+
primitives = @primitives
|
80
|
+
|
54
81
|
case other
|
55
82
|
when Literal::Types::UnionType
|
56
|
-
other.types.all? do |other_type|
|
57
|
-
|
58
|
-
Literal.subtype?(type, of: other_type)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
else
|
62
|
-
@types.any? do |type|
|
63
|
-
Literal.subtype?(other, of: type)
|
83
|
+
types_have_at_least_one_subtype = other.types.all? do |other_type|
|
84
|
+
primitives.any? { |p| Literal.subtype?(p, of: other_type) } || types.any? { |t| Literal.subtype?(t, of: other_type) }
|
64
85
|
end
|
65
|
-
end
|
66
|
-
end
|
67
86
|
|
68
|
-
|
87
|
+
primitives_have_at_least_one_subtype = other.primitives.all? do |other_primitive|
|
88
|
+
primitives.any? { |p| Literal.subtype?(p, of: other_primitive) } || types.any? { |t| Literal.subtype?(t, of: other_primitive) }
|
89
|
+
end
|
69
90
|
|
70
|
-
|
71
|
-
|
72
|
-
(
|
91
|
+
types_have_at_least_one_subtype && primitives_have_at_least_one_subtype
|
92
|
+
else
|
93
|
+
types.any? { |t| Literal.subtype?(other, of: t) } || primitives.any? { |p| Literal.subtype?(other, of: p) }
|
73
94
|
end
|
74
95
|
end
|
75
96
|
|
data/lib/literal/types.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Literal::Types
|
4
|
+
extend self
|
5
|
+
|
4
6
|
autoload :AnyType, "literal/types/any_type"
|
5
7
|
autoload :ArrayType, "literal/types/array_type"
|
6
8
|
autoload :BooleanType, "literal/types/boolean_type"
|
@@ -26,125 +28,175 @@ module Literal::Types
|
|
26
28
|
autoload :UnionType, "literal/types/union_type"
|
27
29
|
autoload :VoidType, "literal/types/void_type"
|
28
30
|
|
29
|
-
ProcableType = InterfaceType.new(:to_proc).freeze
|
30
|
-
CallableType = InterfaceType.new(:call).freeze
|
31
|
-
LambdaType = ConstraintType.new(Proc, lambda?: true).freeze
|
32
|
-
|
33
|
-
NilableBooleanType = NilableType.new(BooleanType::Instance).freeze
|
34
|
-
NilableCallableType = NilableType.new(CallableType).freeze
|
35
|
-
NilableJSONDataType = NilableType.new(JSONDataType).freeze
|
36
|
-
NilableLambdaType = NilableType.new(LambdaType).freeze
|
37
|
-
NilableProcableType = NilableType.new(ProcableType).freeze
|
38
|
-
|
39
31
|
# Matches any value except `nil`. Use `_Any?` or `_Void` to match any value including `nil`.
|
32
|
+
# ```ruby
|
33
|
+
# _Any
|
34
|
+
# ```
|
40
35
|
def _Any
|
41
36
|
AnyType::Instance
|
42
37
|
end
|
43
38
|
|
39
|
+
# Matches any value including `nil`. This is the same as `_Void` and the opposite of `_Never`.
|
40
|
+
# ```ruby
|
41
|
+
# _Any?
|
42
|
+
# ```
|
44
43
|
def _Any?
|
45
44
|
VoidType::Instance
|
46
45
|
end
|
47
46
|
|
48
|
-
# Matches if the value is an `Array` and all the elements match the given type.
|
49
|
-
|
50
|
-
|
47
|
+
# Matches if the value is an `Array` and all the elements of the array match the given type.
|
48
|
+
# ```ruby
|
49
|
+
# _Array(String)
|
50
|
+
# ```
|
51
|
+
def _Array(type)
|
52
|
+
ArrayType.new(type)
|
51
53
|
end
|
52
54
|
|
53
|
-
# Nilable version of `_Array
|
54
|
-
|
55
|
-
|
56
|
-
|
55
|
+
# Nilable version of `_Array`.
|
56
|
+
# ```ruby
|
57
|
+
# _Array?(String)
|
58
|
+
# ```
|
59
|
+
def _Array?(type)
|
60
|
+
_Nilable(
|
61
|
+
_Array(type)
|
57
62
|
)
|
58
63
|
end
|
59
64
|
|
60
|
-
# Matches if the value is `true` or `false`.
|
65
|
+
# Matches if the value is either `true` or `false`. This is equivalent to `_Union(true, false)`.
|
66
|
+
# ```ruby
|
67
|
+
# _Boolean
|
68
|
+
# ```
|
61
69
|
def _Boolean
|
62
70
|
BooleanType::Instance
|
63
71
|
end
|
64
72
|
|
65
|
-
# Nilable version of `_Boolean
|
73
|
+
# Nilable version of `_Boolean`.
|
74
|
+
# ```ruby
|
75
|
+
# _Boolean?
|
76
|
+
# ```
|
66
77
|
def _Boolean?
|
67
78
|
NilableBooleanType
|
68
79
|
end
|
69
80
|
|
70
81
|
# Matches if the value responds to `#call`.
|
82
|
+
# ```ruby
|
83
|
+
# _Callable
|
84
|
+
# ```
|
71
85
|
def _Callable
|
72
86
|
CallableType
|
73
87
|
end
|
74
88
|
|
75
|
-
#
|
89
|
+
# Nilable version of `_Callable`.
|
90
|
+
# ```ruby
|
91
|
+
# _Callable?
|
92
|
+
# ```
|
76
93
|
def _Callable?
|
77
94
|
NilableCallableType
|
78
95
|
end
|
79
96
|
|
80
97
|
# Matches if the value either the given class or a subclass of it.
|
81
|
-
|
82
|
-
|
98
|
+
# ```ruby
|
99
|
+
# _Class(ActiveRecord::Base)
|
100
|
+
# ```
|
101
|
+
def _Class(expected_class)
|
102
|
+
ClassType.new(expected_class)
|
83
103
|
end
|
84
104
|
|
85
|
-
# Nilable version of `_Class
|
105
|
+
# Nilable version of `_Class`.
|
106
|
+
# ```ruby
|
107
|
+
# _Class?(ActiveRecord::Base)
|
108
|
+
# ```
|
86
109
|
def _Class?(...)
|
87
|
-
|
88
|
-
|
110
|
+
_Nilable(
|
111
|
+
_Class(...)
|
89
112
|
)
|
90
113
|
end
|
91
114
|
|
92
115
|
# Similar to `_Intersection`, but allows you to specify attribute constraints as keyword arguments.
|
93
|
-
#
|
94
|
-
#
|
95
|
-
|
96
|
-
|
116
|
+
# ```ruby
|
117
|
+
# _Constraint(Array, size: 1..3)
|
118
|
+
# ```
|
119
|
+
def _Constraint(*a, **k)
|
120
|
+
if a.length == 1 && k.length == 0
|
121
|
+
a[0]
|
122
|
+
else
|
123
|
+
ConstraintType.new(*a, **k)
|
124
|
+
end
|
97
125
|
end
|
98
126
|
|
99
127
|
# Nilable version of `_Constraint`
|
128
|
+
# ```ruby
|
129
|
+
# _Constraint?(Array, size: 1..3)
|
130
|
+
# ```
|
100
131
|
def _Constraint?(...)
|
101
|
-
|
102
|
-
|
132
|
+
_Nilable(
|
133
|
+
_Constraint(...)
|
103
134
|
)
|
104
135
|
end
|
105
136
|
|
106
137
|
# Matches if the value is a `Date` and matches the given constraints.
|
107
|
-
# If you don't need any constraints, use `Date` instead of `_Date`.
|
138
|
+
# If you don't need any constraints, use `Date` instead of `_Date`. See also `_Constraint`.
|
139
|
+
# ```ruby
|
140
|
+
# _Date((Date.today)..)
|
141
|
+
# _Date(year: 2025)
|
142
|
+
# ```
|
108
143
|
def _Date(...)
|
109
144
|
_Constraint(Date, ...)
|
110
145
|
end
|
111
146
|
|
112
|
-
# Nilable version of `_Date
|
147
|
+
# Nilable version of `_Date`.
|
113
148
|
def _Date?(...)
|
114
149
|
_Nilable(
|
115
150
|
_Date(...)
|
116
151
|
)
|
117
152
|
end
|
118
153
|
|
119
|
-
|
120
|
-
|
154
|
+
# Takes a type as a block so it can be resolved when needed. This is useful if declaring your type now would cause an error because constants haven’t been defined yet.
|
155
|
+
# ```ruby
|
156
|
+
# _Deferred { _Class(SomeFutureConstant) }
|
157
|
+
# ```
|
158
|
+
def _Deferred(&type)
|
159
|
+
DeferredType.new(&type)
|
160
|
+
end
|
161
|
+
|
162
|
+
# Nilable version of `_Deferred`.
|
163
|
+
def _Deferred?(&type)
|
164
|
+
_Nilable(
|
165
|
+
_Deferred(&type)
|
166
|
+
)
|
121
167
|
end
|
122
168
|
|
123
169
|
# Matches if the value is a descendant of the given class.
|
170
|
+
# ```ruby
|
171
|
+
# _Descendant(ActiveRecord::Base)
|
172
|
+
# ```
|
124
173
|
def _Descendant(...)
|
125
174
|
DescendantType.new(...)
|
126
175
|
end
|
127
176
|
|
128
|
-
# Nilable version of `_Descendant
|
177
|
+
# Nilable version of `_Descendant`.
|
129
178
|
def _Descendant?(...)
|
130
|
-
|
131
|
-
|
179
|
+
_Nilable(
|
180
|
+
_Descendant(...)
|
132
181
|
)
|
133
182
|
end
|
134
183
|
|
135
184
|
# Matches if the value is an `Enumerable` and all its elements match the given type.
|
136
|
-
|
137
|
-
|
185
|
+
# ```ruby
|
186
|
+
# _Enumerable(String)
|
187
|
+
# ```
|
188
|
+
def _Enumerable(type)
|
189
|
+
EnumerableType.new(type)
|
138
190
|
end
|
139
191
|
|
140
|
-
# Nilable version of `_Enumerable
|
192
|
+
# Nilable version of `_Enumerable`.
|
141
193
|
def _Enumerable?(...)
|
142
|
-
|
143
|
-
|
194
|
+
_Nilable(
|
195
|
+
_Enumerable(...)
|
144
196
|
)
|
145
197
|
end
|
146
198
|
|
147
|
-
# Matches *"falsy"* values (`nil` and `false`).
|
199
|
+
# Matches *"falsy"* values (`nil` and `false`). This is equivalent to `_Nilable(false)` or `_Union(nil, false)`.
|
148
200
|
def _Falsy
|
149
201
|
FalsyType::Instance
|
150
202
|
end
|
@@ -152,11 +204,14 @@ module Literal::Types
|
|
152
204
|
# Matches if the value is a `Float` and matches the given constraints.
|
153
205
|
# You could use a `Range`, for example, as a constraint.
|
154
206
|
# If you don't need a constraint, use `Float` instead of `_Float`.
|
207
|
+
# ```ruby
|
208
|
+
# _Float(5..10)
|
209
|
+
# ```
|
155
210
|
def _Float(...)
|
156
211
|
_Constraint(Float, ...)
|
157
212
|
end
|
158
213
|
|
159
|
-
# Nilable version of `_Float
|
214
|
+
# Nilable version of `_Float`.
|
160
215
|
def _Float?(...)
|
161
216
|
_Nilable(
|
162
217
|
_Float(...)
|
@@ -170,8 +225,8 @@ module Literal::Types
|
|
170
225
|
|
171
226
|
# Nilable version of `_Frozen`
|
172
227
|
def _Frozen?(...)
|
173
|
-
|
174
|
-
|
228
|
+
_Nilable(
|
229
|
+
_Frozen(...)
|
175
230
|
)
|
176
231
|
end
|
177
232
|
|
@@ -182,8 +237,8 @@ module Literal::Types
|
|
182
237
|
|
183
238
|
# Nilable version of `_Hash`
|
184
239
|
def _Hash?(...)
|
185
|
-
|
186
|
-
|
240
|
+
_Nilable(
|
241
|
+
_Hash(...)
|
187
242
|
)
|
188
243
|
end
|
189
244
|
|
@@ -210,8 +265,8 @@ module Literal::Types
|
|
210
265
|
|
211
266
|
# Nilable version of `_Interface`
|
212
267
|
def _Interface?(...)
|
213
|
-
|
214
|
-
|
268
|
+
_Nilable(
|
269
|
+
_Interface(...)
|
215
270
|
)
|
216
271
|
end
|
217
272
|
|
@@ -222,8 +277,8 @@ module Literal::Types
|
|
222
277
|
|
223
278
|
# Nilable version of `_Intersection`
|
224
279
|
def _Intersection?(...)
|
225
|
-
|
226
|
-
|
280
|
+
_Nilable(
|
281
|
+
_Intersection(...)
|
227
282
|
)
|
228
283
|
end
|
229
284
|
|
@@ -247,14 +302,20 @@ module Literal::Types
|
|
247
302
|
NilableLambdaType
|
248
303
|
end
|
249
304
|
|
305
|
+
# ```ruby
|
306
|
+
# _Map(name: String, age: Integer)
|
307
|
+
# ```
|
250
308
|
def _Map(...)
|
251
309
|
MapType.new(...)
|
252
310
|
end
|
253
311
|
|
254
312
|
# Nilable version of `_Map`
|
313
|
+
# ```ruby
|
314
|
+
# _Map?(name: String, age: Integer)
|
315
|
+
# ```
|
255
316
|
def _Map?(...)
|
256
|
-
|
257
|
-
|
317
|
+
_Nilable(
|
318
|
+
_Map(...)
|
258
319
|
)
|
259
320
|
end
|
260
321
|
|
@@ -295,8 +356,8 @@ module Literal::Types
|
|
295
356
|
|
296
357
|
# Nilable version of `_Range`
|
297
358
|
def _Range?(...)
|
298
|
-
|
299
|
-
|
359
|
+
_Nilable(
|
360
|
+
_Range(...)
|
300
361
|
)
|
301
362
|
end
|
302
363
|
|
@@ -307,8 +368,8 @@ module Literal::Types
|
|
307
368
|
|
308
369
|
# Nilable version of `_Set`
|
309
370
|
def _Set?(...)
|
310
|
-
|
311
|
-
|
371
|
+
_Nilable(
|
372
|
+
_Set(...)
|
312
373
|
)
|
313
374
|
end
|
314
375
|
|
@@ -356,14 +417,20 @@ module Literal::Types
|
|
356
417
|
end
|
357
418
|
|
358
419
|
# Matches if the value is an `Array` and each element matches the given types in order.
|
420
|
+
# ```ruby
|
421
|
+
# _Tuple(String, Integer, Integer)
|
422
|
+
# ```
|
359
423
|
def _Tuple(...)
|
360
424
|
TupleType.new(...)
|
361
425
|
end
|
362
426
|
|
363
427
|
# Nilable version of `_Typle`
|
428
|
+
# ```ruby
|
429
|
+
# _Tuple?(String, Integer, Integer)
|
430
|
+
# ```
|
364
431
|
def _Tuple?(...)
|
365
|
-
|
366
|
-
|
432
|
+
_Nilable(
|
433
|
+
_Tuple(...)
|
367
434
|
)
|
368
435
|
end
|
369
436
|
|
@@ -374,12 +441,22 @@ module Literal::Types
|
|
374
441
|
|
375
442
|
# Nilable version of `_Union`
|
376
443
|
def _Union?(...)
|
377
|
-
|
378
|
-
|
444
|
+
_Nilable(
|
445
|
+
_Union(...)
|
379
446
|
)
|
380
447
|
end
|
381
448
|
|
382
449
|
def _Void
|
383
450
|
VoidType::Instance
|
384
451
|
end
|
452
|
+
|
453
|
+
ProcableType = _Interface(:to_proc)
|
454
|
+
CallableType = _Interface(:call)
|
455
|
+
LambdaType = _Constraint(Proc, lambda?: true)
|
456
|
+
|
457
|
+
NilableBooleanType = _Nilable(BooleanType::Instance)
|
458
|
+
NilableCallableType = _Nilable(CallableType)
|
459
|
+
NilableJSONDataType = _Nilable(JSONDataType)
|
460
|
+
NilableLambdaType = _Nilable(LambdaType)
|
461
|
+
NilableProcableType = _Nilable(ProcableType)
|
385
462
|
end
|
data/lib/literal/version.rb
CHANGED
data/lib/literal.rb
CHANGED
@@ -63,15 +63,35 @@ module Literal
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def self.subtype?(type, of:)
|
66
|
-
|
66
|
+
supertype = of
|
67
|
+
subtype = type
|
67
68
|
|
68
|
-
|
69
|
+
subtype = subtype.block.call if Types::DeferredType === subtype
|
70
|
+
|
71
|
+
return true if supertype == subtype
|
72
|
+
|
73
|
+
case supertype
|
69
74
|
when Literal::Type
|
70
|
-
|
75
|
+
supertype >= subtype
|
71
76
|
when Module
|
72
|
-
|
77
|
+
case subtype
|
78
|
+
when Module
|
79
|
+
supertype >= subtype
|
80
|
+
when Numeric
|
81
|
+
Numeric >= supertype
|
82
|
+
when String
|
83
|
+
String >= supertype
|
84
|
+
when Symbol
|
85
|
+
Symbol >= supertype
|
86
|
+
when ::Array
|
87
|
+
::Array >= supertype
|
88
|
+
when ::Hash
|
89
|
+
::Hash >= supertype
|
90
|
+
else
|
91
|
+
false
|
92
|
+
end
|
73
93
|
when Range
|
74
|
-
|
94
|
+
supertype.cover?(subtype)
|
75
95
|
else
|
76
96
|
false
|
77
97
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: literal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Drapper
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-03-10 00:00:00.000000000 Z
|
11
11
|
dependencies: []
|
12
12
|
description: Enums, properties, generics, structured objects and runtime type checking.
|
13
13
|
email:
|