literal 0.2.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
- # Matches any value except `nil`. Use `_Nilable(_Any)` or `_Void` to match any value including `nil`.
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
- Literal::Types::AnyType
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
- Literal::Types::ArrayType.new(...)
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
- Literal::Types::BooleanType
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
- Literal::Types::CallableType
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
- Literal::Types::ClassType.new(...)
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
- Literal::Types::ConstraintType.new(...)
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
- Literal::Types::DescendantType.new(...)
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
- Literal::Types::EnumerableType.new(...)
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
- Literal::Types::FalsyType
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
- Literal::Types::FloatType.new(...)
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
- Literal::Types::FrozenType.new(...)
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
- Literal::Types::HashType.new(...)
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
- Literal::Types::IntegerType.new(...)
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
- Literal::Types::InterfaceType.new(...)
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
- Literal::Types::IntersectionType.new(...)
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
- Literal::Types::JSONDataType
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
- Literal::Types::LambdaType
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
- Literal::Types::MapType.new(...)
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
- Literal::Types::NeverType
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
- Literal::Types::NilableType.new(...)
253
+ NilableType.new(...)
141
254
  end
142
255
 
143
256
  # Matches if the given type is *not* matched.
144
257
  def _Not(...)
145
- Literal::Types::NotType.new(...)
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
- Literal::Types::ProcableType
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
- Literal::Types::RangeType.new(...)
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
- Literal::Types::SetType.new(...)
285
+ SetType.new(...)
161
286
  end
162
287
 
163
- # Ensures a value matches the given shape of a Hash
164
- def _Shape(...)
165
- Literal::Types::ShapeType.new(...)
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
- Literal::Types::StringType.new(...)
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
- Literal::Types::SymbolType.new(...)
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
- Literal::Types::TruthyType
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
- Literal::Types::TupleType.new(...)
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
- Literal::Types::UnionType.new(...)
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
- Literal::Types::VoidType
350
+ VoidType
196
351
  end
197
352
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Literal
4
- VERSION = "0.2.1"
4
+ VERSION = "1.0.0"
5
5
  end
data/lib/literal.rb CHANGED
@@ -25,11 +25,16 @@ module Literal
25
25
  end
26
26
  end
27
27
 
28
- def self.check(value, type)
29
- if TYPE_CHECKS_DISABLED || type === value
28
+ def self.check(actual:, expected:)
29
+ if expected === actual
30
30
  true
31
31
  else
32
- raise Literal::TypeError.expected(value, to_be_a: type)
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.2.1
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-06-30 00:00:00.000000000 Z
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://github.com/joeldrapper/literal
74
+ homepage: https://literal.fun
71
75
  licenses:
72
76
  - MIT
73
77
  metadata:
74
- homepage_uri: https://github.com/joeldrapper/literal
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.13
98
+ rubygems_version: 3.5.18
95
99
  signing_key:
96
100
  specification_version: 4
97
- summary: A literal Ruby gem
101
+ summary: Enums, properties, generics, structured objects and runtime type checking.
98
102
  test_files: []
data/lib/literal.test.rb DELETED
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- test do
4
- expect(Literal::VERSION).to_be_a String
5
- end