literal 0.2.1 → 1.0.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/README.md +2 -157
- data/lib/literal/data_structure.rb +24 -15
- data/lib/literal/enum.rb +28 -14
- data/lib/literal/errors/type_error.rb +76 -3
- data/lib/literal/properties/data_schema.rb +3 -4
- data/lib/literal/properties/schema.rb +57 -7
- data/lib/literal/properties.rb +18 -4
- data/lib/literal/property.rb +47 -20
- data/lib/literal/rails/enum_serializer.rb +20 -0
- data/lib/literal/rails/enum_type.rb +41 -0
- data/lib/literal/rails/patches/active_record.rb +31 -0
- data/lib/literal/rails.rb +9 -0
- data/lib/literal/railtie.rb +13 -0
- data/lib/literal/types/array_type.rb +13 -1
- data/lib/literal/types/boolean_type.rb +0 -6
- data/lib/literal/types/constraint_type.rb +32 -3
- data/lib/literal/types/enumerable_type.rb +1 -1
- data/lib/literal/types/float_type.rb +1 -1
- data/lib/literal/types/hash_type.rb +7 -1
- data/lib/literal/types/integer_type.rb +1 -1
- data/lib/literal/types/json_data_type.rb +3 -1
- data/lib/literal/types/map_type.rb +15 -1
- data/lib/literal/types/set_type.rb +7 -1
- data/lib/literal/types/string_type.rb +1 -1
- data/lib/literal/types/symbol_type.rb +1 -1
- data/lib/literal/types/tuple_type.rb +11 -1
- data/lib/literal/types/union_type.rb +8 -2
- data/lib/literal/types.rb +190 -35
- data/lib/literal/version.rb +1 -1
- data/lib/literal.rb +8 -3
- metadata +12 -8
- data/lib/literal.test.rb +0 -5
data/lib/literal/types.rb
CHANGED
@@ -25,7 +25,6 @@ module Literal::Types
|
|
25
25
|
autoload :ProcableType, "literal/types/procable_type"
|
26
26
|
autoload :RangeType, "literal/types/range_type"
|
27
27
|
autoload :SetType, "literal/types/set_type"
|
28
|
-
autoload :ShapeType, "literal/types/shape_type"
|
29
28
|
autoload :StringType, "literal/types/string_type"
|
30
29
|
autoload :SymbolType, "literal/types/symbol_type"
|
31
30
|
autoload :TruthyType, "literal/types/truthy_type"
|
@@ -33,68 +32,144 @@ module Literal::Types
|
|
33
32
|
autoload :UnionType, "literal/types/union_type"
|
34
33
|
autoload :VoidType, "literal/types/void_type"
|
35
34
|
|
36
|
-
|
35
|
+
NilableBooleanType = NilableType.new(BooleanType)
|
36
|
+
NilableCallableType = NilableType.new(CallableType)
|
37
|
+
NilableJSONDataType = NilableType.new(JSONDataType)
|
38
|
+
NilableLambdaType = NilableType.new(LambdaType)
|
39
|
+
NilableProcableType = NilableType.new(ProcableType)
|
40
|
+
|
41
|
+
# Matches any value except `nil`. Use `_Any?` or `_Unit` to match any value including `nil`.
|
37
42
|
def _Any
|
38
|
-
|
43
|
+
AnyType
|
44
|
+
end
|
45
|
+
|
46
|
+
def _Any?
|
47
|
+
VoidType
|
39
48
|
end
|
40
49
|
|
41
50
|
# Matches if the value is an `Array` and all the elements match the given type.
|
42
51
|
def _Array(...)
|
43
|
-
|
52
|
+
ArrayType.new(...)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Nilable version of `_Array`
|
56
|
+
def _Array?(...)
|
57
|
+
NilableType.new(
|
58
|
+
ArrayType.new(...),
|
59
|
+
)
|
44
60
|
end
|
45
61
|
|
46
62
|
# Matches if the value is `true` or `false`.
|
47
63
|
def _Boolean
|
48
|
-
|
64
|
+
BooleanType
|
65
|
+
end
|
66
|
+
|
67
|
+
# Nilable version of `_Boolean`
|
68
|
+
def _Boolean?
|
69
|
+
NilableBooleanType
|
49
70
|
end
|
50
71
|
|
51
72
|
# Matches if the value responds to `#call`.
|
52
73
|
def _Callable
|
53
|
-
|
74
|
+
CallableType
|
75
|
+
end
|
76
|
+
|
77
|
+
# Nilabl version of `_Callable`
|
78
|
+
def _Callable?
|
79
|
+
NilableCallableType
|
54
80
|
end
|
55
81
|
|
56
82
|
# Matches if the value either the given class or a subclass of it.
|
57
83
|
def _Class(...)
|
58
|
-
|
84
|
+
ClassType.new(...)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Nilable version of `_Class`
|
88
|
+
def _Class?(...)
|
89
|
+
NilableType.new(
|
90
|
+
ClassType.new(...),
|
91
|
+
)
|
59
92
|
end
|
60
93
|
|
61
94
|
# Similar to `_Intersection`, but allows you to specify attribute constraints as keyword arguments.
|
62
95
|
# @example
|
63
96
|
# _Constraint(Array, size: 1..3)
|
64
97
|
def _Constraint(...)
|
65
|
-
|
98
|
+
ConstraintType.new(...)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Nilable version of `_Constraint`
|
102
|
+
def _Constraint?(...)
|
103
|
+
NilableType.new(
|
104
|
+
ConstraintType.new(...),
|
105
|
+
)
|
66
106
|
end
|
67
107
|
|
68
108
|
# Matches if the value is a descendant of the given class.
|
69
109
|
def _Descendant(...)
|
70
|
-
|
110
|
+
DescendantType.new(...)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Nilable version of `_Descendant`
|
114
|
+
def _Descendant?(...)
|
115
|
+
NilableType.new(
|
116
|
+
DescendantType.new(...),
|
117
|
+
)
|
71
118
|
end
|
72
119
|
|
73
120
|
# Matches if the value is an `Enumerable` and all its elements match the given type.
|
74
121
|
def _Enumerable(...)
|
75
|
-
|
122
|
+
EnumerableType.new(...)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Nilable version of `_Enumerable`
|
126
|
+
def _Enumerable?(...)
|
127
|
+
NilableType.new(
|
128
|
+
EnumerableType.new(...),
|
129
|
+
)
|
76
130
|
end
|
77
131
|
|
78
132
|
# Matches *"falsy"* values (`nil` and `false`).
|
79
133
|
def _Falsy
|
80
|
-
|
134
|
+
FalsyType
|
81
135
|
end
|
82
136
|
|
83
137
|
# Matches if the value is a `Float` and matches the given constraint.
|
84
138
|
# You could use a `Range`, for example, as a constraint.
|
85
139
|
# If you don't need a constraint, use `Float` instead of `_Float`.
|
86
140
|
def _Float(...)
|
87
|
-
|
141
|
+
FloatType.new(...)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Nilable version of `_Float`
|
145
|
+
def _Float?(...)
|
146
|
+
NilableType.new(
|
147
|
+
FloatType.new(...),
|
148
|
+
)
|
88
149
|
end
|
89
150
|
|
90
151
|
# Matches if the value is *frozen*.
|
91
152
|
def _Frozen(...)
|
92
|
-
|
153
|
+
FrozenType.new(...)
|
154
|
+
end
|
155
|
+
|
156
|
+
# Nilable version of `_Frozen`
|
157
|
+
def _Frozen?(...)
|
158
|
+
NilableType.new(
|
159
|
+
FrozenType.new(...),
|
160
|
+
)
|
93
161
|
end
|
94
162
|
|
95
163
|
# Matches if the value is a `Hash` and all the keys and values match the given types.
|
96
164
|
def _Hash(...)
|
97
|
-
|
165
|
+
HashType.new(...)
|
166
|
+
end
|
167
|
+
|
168
|
+
# Nilable version of `_Hash`
|
169
|
+
def _Hash?
|
170
|
+
NilableType.new(
|
171
|
+
HashType.new,
|
172
|
+
)
|
98
173
|
end
|
99
174
|
|
100
175
|
# Matches if the value is an `Integer` and matches the given constraint.
|
@@ -103,95 +178,175 @@ module Literal::Types
|
|
103
178
|
# @example
|
104
179
|
# attribute :age, _Integer(18..127)
|
105
180
|
def _Integer(...)
|
106
|
-
|
181
|
+
IntegerType.new(...)
|
182
|
+
end
|
183
|
+
|
184
|
+
# Nilable version of `_Integer`
|
185
|
+
def _Integer?(...)
|
186
|
+
NilableType.new(
|
187
|
+
IntegerType(...),
|
188
|
+
)
|
107
189
|
end
|
108
190
|
|
109
191
|
# Matches if the value responds to all the given methods.
|
110
192
|
def _Interface(...)
|
111
|
-
|
193
|
+
InterfaceType.new(...)
|
194
|
+
end
|
195
|
+
|
196
|
+
# Nilable version of `_Interface`
|
197
|
+
def _Interface?(...)
|
198
|
+
NilableType.new(
|
199
|
+
InterfaceType.new(...),
|
200
|
+
)
|
112
201
|
end
|
113
202
|
|
114
203
|
# Matches if *all* given types are matched.
|
115
204
|
def _Intersection(...)
|
116
|
-
|
205
|
+
IntersectionType.new(...)
|
206
|
+
end
|
207
|
+
|
208
|
+
# Nilable version of `_Intersection`
|
209
|
+
def _Intersection?(...)
|
210
|
+
NilableType.new(
|
211
|
+
IntersectionType.new(...),
|
212
|
+
)
|
117
213
|
end
|
118
214
|
|
119
215
|
# Ensures the value is valid JSON data (i.e. it came from JSON.parse).
|
120
216
|
def _JSONData
|
121
|
-
|
217
|
+
JSONDataType
|
218
|
+
end
|
219
|
+
|
220
|
+
# Nilable version of `_JSONData`
|
221
|
+
def _JSONData?
|
222
|
+
NilableJSONDataType
|
122
223
|
end
|
123
224
|
|
124
225
|
# Matches if the value is a `Proc` and `#lambda?` returns truthy.
|
125
226
|
def _Lambda
|
126
|
-
|
227
|
+
LambdaType
|
228
|
+
end
|
229
|
+
|
230
|
+
# Nilable version of `_Lambda`
|
231
|
+
def _Lambda?
|
232
|
+
NilableLambdaType
|
127
233
|
end
|
128
234
|
|
129
235
|
def _Map(...)
|
130
|
-
|
236
|
+
MapType.new(...)
|
237
|
+
end
|
238
|
+
|
239
|
+
# Nilable version of `_Map`
|
240
|
+
def _Map?(...)
|
241
|
+
NilableType.new(
|
242
|
+
MapType.new(...),
|
243
|
+
)
|
131
244
|
end
|
132
245
|
|
133
246
|
# Never matches any value.
|
134
247
|
def _Never
|
135
|
-
|
248
|
+
NeverType
|
136
249
|
end
|
137
250
|
|
138
251
|
# Matches if the value is either `nil` or the given type.
|
139
252
|
def _Nilable(...)
|
140
|
-
|
253
|
+
NilableType.new(...)
|
141
254
|
end
|
142
255
|
|
143
256
|
# Matches if the given type is *not* matched.
|
144
257
|
def _Not(...)
|
145
|
-
|
258
|
+
NotType.new(...)
|
146
259
|
end
|
147
260
|
|
148
261
|
# Matches if the value is a `Proc` or responds to `#to_proc`.
|
149
262
|
def _Procable
|
150
|
-
|
263
|
+
ProcableType
|
264
|
+
end
|
265
|
+
|
266
|
+
# Nilable version ofo `_Procable`
|
267
|
+
def _Procable?
|
268
|
+
NilableProcableType
|
151
269
|
end
|
152
270
|
|
153
271
|
# Matches if the value is a `Range` of the given type.
|
154
272
|
def _Range(...)
|
155
|
-
|
273
|
+
RangeType.new(...)
|
274
|
+
end
|
275
|
+
|
276
|
+
# Nilable version of `_Range`
|
277
|
+
def _Range?(...)
|
278
|
+
NilableType.new(
|
279
|
+
RangeType.new(...),
|
280
|
+
)
|
156
281
|
end
|
157
282
|
|
158
283
|
# Matches if the value is a `Set` and all the elements match the given type.
|
159
284
|
def _Set(...)
|
160
|
-
|
285
|
+
SetType.new(...)
|
161
286
|
end
|
162
287
|
|
163
|
-
#
|
164
|
-
def
|
165
|
-
|
288
|
+
# Nilable version of `_Set`
|
289
|
+
def _Set?(...)
|
290
|
+
NilableType.new(
|
291
|
+
SetType.new(...),
|
292
|
+
)
|
166
293
|
end
|
167
294
|
|
168
295
|
# Matches if the value is a `String` and matches the given constraints.
|
169
296
|
# If you don't need any constraints, use `String` instead of `_String`.
|
170
297
|
def _String(...)
|
171
|
-
|
298
|
+
StringType.new(...)
|
299
|
+
end
|
300
|
+
|
301
|
+
# Nilable version of `_String`
|
302
|
+
def _String?(...)
|
303
|
+
NilableType.new(
|
304
|
+
StringType.new(...),
|
305
|
+
)
|
172
306
|
end
|
173
307
|
|
174
308
|
# Matches if the value is a `Symbol` and matches the given constraint.
|
175
309
|
def _Symbol(...)
|
176
|
-
|
310
|
+
SymbolType.new(...)
|
311
|
+
end
|
312
|
+
|
313
|
+
# Nilable version of `_Symbol`
|
314
|
+
def _Symbol?(...)
|
315
|
+
NilableType.new(
|
316
|
+
SymbolType.new(...),
|
317
|
+
)
|
177
318
|
end
|
178
319
|
|
179
320
|
# Matches *"truthy"* values (anything except `nil` and `false`).
|
180
321
|
def _Truthy
|
181
|
-
|
322
|
+
TruthyType
|
182
323
|
end
|
183
324
|
|
184
325
|
# Matches if the value is an `Array` and each element matches the given types in order.
|
185
326
|
def _Tuple(...)
|
186
|
-
|
327
|
+
TupleType.new(...)
|
328
|
+
end
|
329
|
+
|
330
|
+
# Nilable version of `_Typle`
|
331
|
+
def _Tuple?(...)
|
332
|
+
NilableType.new(
|
333
|
+
TupleType.new(...),
|
334
|
+
)
|
187
335
|
end
|
188
336
|
|
189
337
|
# Matches if *any* given type is matched.
|
190
338
|
def _Union(...)
|
191
|
-
|
339
|
+
UnionType.new(...)
|
340
|
+
end
|
341
|
+
|
342
|
+
# Nilable version of `_Union`
|
343
|
+
def _Union?(...)
|
344
|
+
NilableType.new(
|
345
|
+
UnionType.new(...),
|
346
|
+
)
|
192
347
|
end
|
193
348
|
|
194
349
|
def _Void
|
195
|
-
|
350
|
+
VoidType
|
196
351
|
end
|
197
352
|
end
|
data/lib/literal/version.rb
CHANGED
data/lib/literal.rb
CHANGED
@@ -25,11 +25,16 @@ module Literal
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
def self.check(
|
29
|
-
if
|
28
|
+
def self.check(actual:, expected:)
|
29
|
+
if expected === actual
|
30
30
|
true
|
31
31
|
else
|
32
|
-
|
32
|
+
context = Literal::TypeError::Context.new(expected:, actual:)
|
33
|
+
expected.record_literal_type_errors(context) if expected.respond_to?(:record_literal_type_errors)
|
34
|
+
yield context if block_given?
|
35
|
+
raise Literal::TypeError.new(context:)
|
33
36
|
end
|
34
37
|
end
|
35
38
|
end
|
39
|
+
|
40
|
+
require_relative "literal/rails" if defined?(Rails)
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: literal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Drapper
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description:
|
13
|
+
description: A literal Ruby gem.
|
14
14
|
email:
|
15
15
|
- joel@drapper.me
|
16
16
|
executables: []
|
@@ -20,7 +20,6 @@ files:
|
|
20
20
|
- LICENSE.txt
|
21
21
|
- README.md
|
22
22
|
- lib/literal.rb
|
23
|
-
- lib/literal.test.rb
|
24
23
|
- lib/literal/data.rb
|
25
24
|
- lib/literal/data_property.rb
|
26
25
|
- lib/literal/data_structure.rb
|
@@ -34,6 +33,11 @@ files:
|
|
34
33
|
- lib/literal/properties/data_schema.rb
|
35
34
|
- lib/literal/properties/schema.rb
|
36
35
|
- lib/literal/property.rb
|
36
|
+
- lib/literal/rails.rb
|
37
|
+
- lib/literal/rails/enum_serializer.rb
|
38
|
+
- lib/literal/rails/enum_type.rb
|
39
|
+
- lib/literal/rails/patches/active_record.rb
|
40
|
+
- lib/literal/railtie.rb
|
37
41
|
- lib/literal/struct.rb
|
38
42
|
- lib/literal/types.rb
|
39
43
|
- lib/literal/types/any_type.rb
|
@@ -67,11 +71,11 @@ files:
|
|
67
71
|
- lib/literal/types/union_type.rb
|
68
72
|
- lib/literal/types/void_type.rb
|
69
73
|
- lib/literal/version.rb
|
70
|
-
homepage: https://
|
74
|
+
homepage: https://literal.fun
|
71
75
|
licenses:
|
72
76
|
- MIT
|
73
77
|
metadata:
|
74
|
-
homepage_uri: https://
|
78
|
+
homepage_uri: https://literal.fun
|
75
79
|
source_code_uri: https://github.com/joeldrapper/literal
|
76
80
|
changelog_uri: https://github.com/joeldrapper/literal/blob/main/CHANGELOG.md
|
77
81
|
funding_uri: https://github.com/sponsors/joeldrapper
|
@@ -91,8 +95,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
95
|
- !ruby/object:Gem::Version
|
92
96
|
version: '0'
|
93
97
|
requirements: []
|
94
|
-
rubygems_version: 3.5.
|
98
|
+
rubygems_version: 3.5.18
|
95
99
|
signing_key:
|
96
100
|
specification_version: 4
|
97
|
-
summary:
|
101
|
+
summary: Enums, properties, generics, structured objects and runtime type checking.
|
98
102
|
test_files: []
|