stannum 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -18,27 +18,6 @@ module Stannum
18
18
  @attributes = {}
19
19
  end
20
20
 
21
- # @!method each
22
- # Iterates through the the attributes by name and attribute object.
23
- #
24
- # @yieldparam name [String] The name of the attribute.
25
- # @yieldparam attribute [Stannum::Attribute] The attribute object.
26
-
27
- # @!method each_key
28
- # Iterates through the the attributes by name.
29
- #
30
- # @yieldparam name [String] The name of the attribute.
31
-
32
- # @!method each_value
33
- # Iterates through the the attributes by attribute object.
34
- #
35
- # @yieldparam attribute [Stannum::Attribute] The attribute object.
36
-
37
- def_delegators :attributes,
38
- :each,
39
- :each_key,
40
- :each_value
41
-
42
21
  # Retrieves the named attribute object.
43
22
  #
44
23
  # @param key [String, Symbol] The name of the requested attribute.
@@ -48,9 +27,17 @@ module Stannum
48
27
  # @raise ArgumentError if the key is invalid.
49
28
  # @raise KeyError if the attribute is not defined.
50
29
  def [](key)
51
- validate_key(key)
30
+ tools.assertions.assert_name(key, as: 'key', error_class: ArgumentError)
31
+
32
+ str = -key.to_s
52
33
 
53
- attributes.fetch(key.to_s)
34
+ each_ancestor do |ancestor|
35
+ next unless ancestor.own_attributes.key?(str)
36
+
37
+ return ancestor.own_attributes[str]
38
+ end
39
+
40
+ {}.fetch(str)
54
41
  end
55
42
 
56
43
  # rubocop:disable Metrics/MethodLength
@@ -81,33 +68,83 @@ module Stannum
81
68
  end
82
69
  # rubocop:enable Metrics/MethodLength
83
70
 
71
+ # Iterates through the the attributes by name and attribute object.
72
+ #
73
+ # @yieldparam name [String] The name of the attribute.
74
+ # @yieldparam attribute [Stannum::Attribute] The attribute object.
75
+ def each(&block)
76
+ return enum_for(:each) { size } unless block_given?
77
+
78
+ each_ancestor do |ancestor|
79
+ ancestor.own_attributes.each(&block)
80
+ end
81
+ end
82
+
83
+ # Iterates through the the attributes by name.
84
+ #
85
+ # @yieldparam name [String] The name of the attribute.
86
+ def each_key(&block)
87
+ return enum_for(:each_key) { size } unless block_given?
88
+
89
+ each_ancestor do |ancestor|
90
+ ancestor.own_attributes.each_key(&block)
91
+ end
92
+ end
93
+
94
+ # Iterates through the the attributes by attribute object.
95
+ #
96
+ # @yieldparam attribute [Stannum::Attribute] The attribute object.
97
+ def each_value(&block)
98
+ return enum_for(:each_value) { size } unless block_given?
99
+
100
+ each_ancestor do |ancestor|
101
+ ancestor.own_attributes.each_value(&block)
102
+ end
103
+ end
104
+
84
105
  # Checks if the given attribute is defined.
85
106
  #
86
107
  # @param key [String, Symbol] the name of the attribute to check.
87
108
  #
88
109
  # @return [Boolean] true if the attribute is defined; otherwise false.
89
110
  def key?(key)
90
- validate_key(key)
111
+ tools.assertions.assert_name(key, as: 'key', error_class: ArgumentError)
91
112
 
92
- attributes.key?(key.to_s)
113
+ each_ancestor.any? do |ancestor|
114
+ ancestor.own_attributes.key?(key.to_s)
115
+ end
93
116
  end
94
117
  alias has_key? key?
95
118
 
119
+ # Returns the defined attribute keys.
120
+ #
121
+ # @return [Array<String>] the attribute keys.
122
+ def keys
123
+ each_key.to_a
124
+ end
125
+
96
126
  # @private
97
127
  def own_attributes
98
128
  @attributes
99
129
  end
100
130
 
101
- private
131
+ # @return [Integer] the number of defined attributes.
132
+ def size
133
+ each_ancestor.reduce(0) do |memo, ancestor|
134
+ memo + ancestor.own_attributes.size
135
+ end
136
+ end
137
+ alias count size
102
138
 
103
- def attributes
104
- ancestors
105
- .reverse_each
106
- .select { |mod| mod.is_a?(Stannum::Schema) }
107
- .map(&:own_attributes)
108
- .reduce(&:merge)
139
+ # Returns the defined attribute value.
140
+ #
141
+ # @return [Array<Stannum::Attribute>] the attribute values.
142
+ def values
143
+ each_value.to_a
109
144
  end
110
145
 
146
+ private
147
+
111
148
  def define_reader(attr_name, reader_name)
112
149
  define_method(reader_name) { @attributes[attr_name] }
113
150
  end
@@ -118,14 +155,18 @@ module Stannum
118
155
  end
119
156
  end
120
157
 
121
- def validate_key(key)
122
- raise ArgumentError, "key can't be blank" if key.nil?
158
+ def each_ancestor
159
+ return enum_for(:each_ancestor) unless block_given?
123
160
 
124
- unless key.is_a?(String) || key.is_a?(Symbol)
125
- raise ArgumentError, 'key must be a String or Symbol'
161
+ ancestors.reverse_each do |ancestor|
162
+ break unless ancestor.is_a?(Stannum::Schema)
163
+
164
+ yield ancestor
126
165
  end
166
+ end
127
167
 
128
- raise ArgumentError, "key can't be blank" if key.to_s.empty?
168
+ def tools
169
+ SleepingKingStudios::Tools::Toolbelt.instance
129
170
  end
130
171
  end
131
172
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'sleeping_king_studios/tools/toolbox/mixin'
4
-
5
- require 'stannum/schema'
3
+ require 'stannum/entities/attributes'
4
+ require 'stannum/entities/constraints'
5
+ require 'stannum/entities/properties'
6
6
 
7
7
  module Stannum
8
8
  # Abstract class for defining objects with structured attributes.
@@ -74,200 +74,10 @@ module Stannum
74
74
  # name: 'Diode',
75
75
  # description: 'A low budget Diode',
76
76
  # ) #=> true
77
- module Struct # rubocop:disable Metrics/ModuleLength
78
- extend SleepingKingStudios::Tools::Toolbox::Mixin
79
-
80
- # Class methods to extend the class when including Stannum::Struct.
81
- module ClassMethods
82
- # rubocop:disable Metrics/MethodLength
83
-
84
- # Defines an attribute on the struct.
85
- #
86
- # When an attribute is defined, each of the following steps is executed:
87
- #
88
- # - Adds the attribute to ::Attributes and the .attributes class method.
89
- # - Adds the attribute to #attributes and the associated methods, such as
90
- # #assign_attributes, #[] and #[]=.
91
- # - Defines reader and writer methods.
92
- # - Adds a type constraint to ::Attributes::Contract, and indirectly to
93
- # ::Contract.
94
- #
95
- # @param attr_name [String, Symbol] The name of the attribute. Must be a
96
- # non-empty String or Symbol.
97
- # @param attr_type [Class, String] The type of the attribute. Must be a
98
- # Class or Module, or the name of a class or module.
99
- # @param options [Hash] Additional options for the attribute.
100
- #
101
- # @option options [Object] :default The default value for the attribute.
102
- # Defaults to nil.
103
- #
104
- # @return [Symbol] The attribute name as a symbol.
105
- def attribute(attr_name, attr_type, **options)
106
- attribute = attributes.define_attribute(
107
- name: attr_name,
108
- type: attr_type,
109
- options: options
110
- )
111
- constraint = Stannum::Constraints::Type.new(
112
- attribute.type,
113
- required: attribute.required?
114
- )
115
-
116
- self::Contract.add_constraint(
117
- constraint,
118
- property: attribute.reader_name
119
- )
120
-
121
- attr_name.intern
122
- end
123
- # rubocop:enable Metrics/MethodLength
124
-
125
- # @return [Stannum::Schema] The Schema object for the Struct.
126
- def attributes
127
- self::Attributes
128
- end
129
-
130
- # Defines a constraint on the struct or one of its properties.
131
- #
132
- # @overload constraint()
133
- # Defines a constraint on the struct.
134
- #
135
- # A new Stannum::Constraint instance will be generated, passing the
136
- # block from .constraint to the new constraint. This constraint will be
137
- # added to the contract.
138
- #
139
- # @yieldparam struct [Stannum::Struct] The struct at the time the
140
- # constraint is evaluated.
141
- #
142
- # @overload constraint(constraint)
143
- # Defines a constraint on the struct.
144
- #
145
- # The given constraint is added to the contract. When the contract is
146
- # evaluated, this constraint will be matched against the struct.
147
- #
148
- # @param constraint [Stannum::Constraints::Base] The constraint to add.
149
- #
150
- # @overload constraint(attr_name)
151
- # Defines a constraint on the given attribute or property.
152
- #
153
- # A new Stannum::Constraint instance will be generated, passing the
154
- # block from .constraint to the new constraint. This constraint will be
155
- # added to the contract.
156
- #
157
- # @param attr_name [String, Symbol] The name of the attribute or
158
- # property to constrain.
159
- #
160
- # @yieldparam value [Object] The value of the attribute or property of
161
- # the struct at the time the constraint is evaluated.
162
- #
163
- # @overload constraint(attr_name, constraint)
164
- # Defines a constraint on the given attribute or property.
165
- #
166
- # The given constraint is added to the contract. When the contract is
167
- # evaluated, this constraint will be matched against the value of the
168
- # attribute or property.
169
- #
170
- # @param attr_name [String, Symbol] The name of the attribute or
171
- # property to constrain.
172
- # @param constraint [Stannum::Constraints::Base] The constraint to add.
173
- def constraint(attr_name = nil, constraint = nil, &block)
174
- attr_name, constraint = resolve_constraint(attr_name, constraint)
175
-
176
- if block_given?
177
- constraint = Stannum::Constraint.new(&block)
178
- else
179
- validate_constraint(constraint)
180
- end
181
-
182
- contract.add_constraint(constraint, property: attr_name)
183
- end
184
-
185
- # @return [Stannum::Contract] The Contract object for the Struct.
186
- def contract
187
- self::Contract
188
- end
189
-
190
- private
191
-
192
- # @api private
193
- #
194
- # Hook to execute when a struct class is subclassed.
195
- def inherited(other)
196
- super
197
-
198
- Struct.build(other) if other.is_a?(Class)
199
- end
200
-
201
- def resolve_constraint(attr_name, constraint)
202
- return [nil, attr_name] if attr_name.is_a?(Stannum::Constraints::Base)
203
-
204
- validate_attribute_name(attr_name)
205
-
206
- [attr_name.nil? ? attr_name : attr_name.intern, constraint]
207
- end
208
-
209
- def validate_attribute_name(name)
210
- return if name.nil?
211
-
212
- unless name.is_a?(String) || name.is_a?(Symbol)
213
- raise ArgumentError, 'attribute must be a String or Symbol'
214
- end
215
-
216
- raise ArgumentError, "attribute can't be blank" if name.empty?
217
- end
218
-
219
- def validate_constraint(constraint)
220
- raise ArgumentError, "constraint can't be blank" if constraint.nil?
221
-
222
- return if constraint.is_a?(Stannum::Constraints::Base)
223
-
224
- raise ArgumentError, 'constraint must be a Stannum::Constraints::Base'
225
- end
226
- end
227
-
228
- class << self
229
- # @private
230
- def build(struct_class)
231
- return if struct_class?(struct_class)
232
-
233
- initialize_attributes(struct_class)
234
- initialize_contract(struct_class)
235
- end
236
-
237
- private
238
-
239
- def included(other)
240
- super
241
-
242
- Struct.build(other) if other.is_a?(Class)
243
- end
244
-
245
- def initialize_attributes(struct_class)
246
- attributes = Stannum::Schema.new
247
-
248
- struct_class.const_set(:Attributes, attributes)
249
-
250
- if struct_class?(struct_class.superclass)
251
- attributes.include(struct_class.superclass::Attributes)
252
- end
253
-
254
- struct_class.include(attributes)
255
- end
256
-
257
- def initialize_contract(struct_class)
258
- contract = Stannum::Contract.new
259
-
260
- struct_class.const_set(:Contract, contract)
261
-
262
- return unless struct_class?(struct_class.superclass)
263
-
264
- contract.concat(struct_class.superclass::Contract)
265
- end
266
-
267
- def struct_class?(struct_class)
268
- struct_class.const_defined?(:Attributes, false)
269
- end
270
- end
77
+ module Struct
78
+ include Stannum::Entities::Properties
79
+ include Stannum::Entities::Attributes
80
+ include Stannum::Entities::Constraints
271
81
 
272
82
  # Initializes the struct with the given attributes.
273
83
  #
@@ -285,160 +95,16 @@ module Stannum
285
95
  #
286
96
  # @raise ArgumentError if given an invalid attributes hash.
287
97
  def initialize(attributes = {})
288
- @attributes = {}
289
-
290
- self.attributes = attributes
291
- end
292
-
293
- # Compares the struct with the other object.
294
- #
295
- # The other object must be an instance of the current class. In addition,
296
- # the attributes hashes of the two objects must be equal.
297
- #
298
- # @return true if the object is a matching struct.
299
- def ==(other)
300
- return false unless other.class == self.class
301
-
302
- raw_attributes == other.raw_attributes
303
- end
304
-
305
- # Retrieves the attribute with the given key.
306
- #
307
- # @param key [String, Symbol] The attribute key.
308
- #
309
- # @return [Object] the value of the attribute.
310
- #
311
- # @raise ArgumentError if the key is not a valid attribute.
312
- def [](key)
313
- validate_attribute_key(key)
314
-
315
- send(self.class::Attributes[key].reader_name)
316
- end
317
-
318
- # Sets the given attribute to the given value.
319
- #
320
- # @param key [String, Symbol] The attribute key.
321
- # @param value [Object] The value for the attribute.
322
- #
323
- # @raise ArgumentError if the key is not a valid attribute.
324
- def []=(key, value)
325
- validate_attribute_key(key)
326
-
327
- send(self.class::Attributes[key].writer_name, value)
328
- end
329
-
330
- # Updates the struct's attributes with the given values.
331
- #
332
- # This method is used to update some (but not all) of the attributes of the
333
- # struct. For each key in the hash, it calls the corresponding writer method
334
- # with the value for that attribute. If the value is nil, this will set the
335
- # attribute value to the default for that attribute.
336
- #
337
- # Any attributes that are not in the given hash are unchanged.
338
- #
339
- # If the attributes hash includes any keys that do not correspond to an
340
- # attribute, the struct will raise an error.
341
- #
342
- # @param attributes [Hash] The initial attributes for the struct.
343
- #
344
- # @raise ArgumentError if the key is not a valid attribute.
345
- #
346
- # @see #attributes=
347
- def assign_attributes(attributes)
348
- unless attributes.is_a?(Hash)
349
- raise ArgumentError, 'attributes must be a Hash'
350
- end
351
-
352
- attributes.each do |attr_name, value|
353
- validate_attribute_key(attr_name)
354
-
355
- attribute = self.class.attributes[attr_name]
356
-
357
- send(attribute.writer_name, value)
358
- end
359
- end
360
- alias assign assign_attributes
361
-
362
- # @return [Hash] the current attributes of the struct.
363
- def attributes
364
- tools.hash_tools.deep_dup(@attributes)
365
- end
366
- alias to_h attributes
367
-
368
- # Replaces the struct's attributes with the given values.
369
- #
370
- # This method is used to update all of the attributes of the struct. For
371
- # each attribute, the writer method is called with the value from the hash,
372
- # or nil if the corresponding key is not present in the hash. Any nil or
373
- # missing keys set the attribute value to the attribute's default value.
374
- #
375
- # If the attributes hash includes any keys that do not correspond to an
376
- # attribute, the struct will raise an error.
377
- #
378
- # @param attributes [Hash] The initial attributes for the struct.
379
- #
380
- # @raise ArgumentError if the key is not a valid attribute.
381
- #
382
- # @see #assign_attributes
383
- def attributes=(attributes) # rubocop:disable Metrics/MethodLength
384
98
  unless attributes.is_a?(Hash)
385
99
  raise ArgumentError, 'attributes must be a Hash'
386
100
  end
387
101
 
388
- attributes.each_key { |attr_name| validate_attribute_key(attr_name) }
389
-
390
- self.class::Attributes.each_value do |attribute|
391
- send(
392
- attribute.writer_name,
393
- attributes.fetch(
394
- attribute.name,
395
- attributes.fetch(attribute.name.intern, attribute.default)
396
- )
397
- )
398
- end
399
- end
400
-
401
- # @return [String] a string representation of the struct and its attributes.
402
- def inspect # rubocop:disable Metrics/AbcSize
403
- if self.class.attributes.each_key.size.zero?
404
- return "#<#{self.class.name}>"
405
- end
406
-
407
- buffer = +"#<#{self.class.name}"
408
-
409
- self.class.attributes.each_key.with_index \
410
- do |attribute, index|
411
- buffer << ',' unless index.zero?
412
- buffer << " #{attribute}: #{@attributes[attribute].inspect}"
413
- end
414
-
415
- buffer << '>'
416
- end
417
-
418
- protected
419
-
420
- def raw_attributes
421
- @attributes
422
- end
423
-
424
- private
425
-
426
- def tools
427
- SleepingKingStudios::Tools::Toolbelt.instance
428
- end
429
-
430
- def validate_attribute_key(key)
431
- raise ArgumentError, "attribute can't be blank" if key.nil?
432
-
433
- unless key.is_a?(String) || key.is_a?(Symbol)
434
- raise ArgumentError, 'attribute must be a String or Symbol'
435
- end
436
-
437
- raise ArgumentError, "attribute can't be blank" if key.empty?
438
-
439
- return if self.class::Attributes.key?(key.to_s)
102
+ super(**attributes)
440
103
 
441
- raise ArgumentError, "unknown attribute #{key.inspect}"
104
+ SleepingKingStudios::Tools::CoreTools.deprecate(
105
+ 'Stannum::Struct',
106
+ 'use Stannum::Entity instead'
107
+ )
442
108
  end
443
109
  end
444
110
  end
@@ -10,7 +10,7 @@ module Stannum
10
10
  # Major version.
11
11
  MAJOR = 0
12
12
  # Minor version.
13
- MINOR = 2
13
+ MINOR = 3
14
14
  # Patch version.
15
15
  PATCH = 0
16
16
  # Prerelease version.
data/lib/stannum.rb CHANGED
@@ -8,9 +8,12 @@ module Stannum
8
8
  autoload :Constraints, 'stannum/constraints'
9
9
  autoload :Contract, 'stannum/contract'
10
10
  autoload :Contracts, 'stannum/contracts'
11
+ autoload :Entities, 'stannum/entities'
12
+ autoload :Entity, 'stannum/entity'
11
13
  autoload :Errors, 'stannum/errors'
12
14
  autoload :Messages, 'stannum/messages'
13
15
  autoload :ParameterValidation, 'stannum/parameter_validation'
16
+ autoload :Schema, 'stannum/schema'
14
17
  autoload :Struct, 'stannum/struct'
15
18
 
16
19
  # @return [String] the absolute path to the gem directory.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stannum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob "Merlin" Smith
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-19 00:00:00.000000000 Z
11
+ date: 2023-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sleeping_king_studios-tools
@@ -16,20 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 1.0.2
19
+ version: 1.1.0
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '1.0'
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: 1.0.2
26
+ version: 1.1.0
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: rspec
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -64,28 +58,28 @@ dependencies:
64
58
  requirements:
65
59
  - - "~>"
66
60
  - !ruby/object:Gem::Version
67
- version: '1.18'
61
+ version: '1.48'
68
62
  type: :development
69
63
  prerelease: false
70
64
  version_requirements: !ruby/object:Gem::Requirement
71
65
  requirements:
72
66
  - - "~>"
73
67
  - !ruby/object:Gem::Version
74
- version: '1.18'
68
+ version: '1.48'
75
69
  - !ruby/object:Gem::Dependency
76
70
  name: rubocop-rspec
77
71
  requirement: !ruby/object:Gem::Requirement
78
72
  requirements:
79
73
  - - "~>"
80
74
  - !ruby/object:Gem::Version
81
- version: '2.4'
75
+ version: '2.19'
82
76
  type: :development
83
77
  prerelease: false
84
78
  version_requirements: !ruby/object:Gem::Requirement
85
79
  requirements:
86
80
  - - "~>"
87
81
  - !ruby/object:Gem::Version
88
- version: '2.4'
82
+ version: '2.19'
89
83
  - !ruby/object:Gem::Dependency
90
84
  name: simplecov
91
85
  requirement: !ruby/object:Gem::Requirement
@@ -130,6 +124,7 @@ files:
130
124
  - lib/stannum/constraints/equality.rb
131
125
  - lib/stannum/constraints/hashes.rb
132
126
  - lib/stannum/constraints/hashes/extra_keys.rb
127
+ - lib/stannum/constraints/hashes/indifferent_extra_keys.rb
133
128
  - lib/stannum/constraints/hashes/indifferent_key.rb
134
129
  - lib/stannum/constraints/identity.rb
135
130
  - lib/stannum/constraints/nothing.rb
@@ -137,6 +132,11 @@ files:
137
132
  - lib/stannum/constraints/parameters/extra_arguments.rb
138
133
  - lib/stannum/constraints/parameters/extra_keywords.rb
139
134
  - lib/stannum/constraints/presence.rb
135
+ - lib/stannum/constraints/properties.rb
136
+ - lib/stannum/constraints/properties/base.rb
137
+ - lib/stannum/constraints/properties/do_not_match_property.rb
138
+ - lib/stannum/constraints/properties/match_property.rb
139
+ - lib/stannum/constraints/properties/matching.rb
140
140
  - lib/stannum/constraints/signature.rb
141
141
  - lib/stannum/constraints/signatures.rb
142
142
  - lib/stannum/constraints/signatures/map.rb
@@ -176,6 +176,11 @@ files:
176
176
  - lib/stannum/contracts/parameters/signature_contract.rb
177
177
  - lib/stannum/contracts/parameters_contract.rb
178
178
  - lib/stannum/contracts/tuple_contract.rb
179
+ - lib/stannum/entities.rb
180
+ - lib/stannum/entities/attributes.rb
181
+ - lib/stannum/entities/constraints.rb
182
+ - lib/stannum/entities/properties.rb
183
+ - lib/stannum/entity.rb
179
184
  - lib/stannum/errors.rb
180
185
  - lib/stannum/messages.rb
181
186
  - lib/stannum/messages/default_loader.rb
@@ -198,7 +203,8 @@ licenses:
198
203
  metadata:
199
204
  bug_tracker_uri: https://github.com/sleepingkingstudios/stannum/issues
200
205
  source_code_uri: https://github.com/sleepingkingstudios/stannum
201
- post_install_message:
206
+ rubygems_mfa_required: 'true'
207
+ post_install_message:
202
208
  rdoc_options: []
203
209
  require_paths:
204
210
  - lib
@@ -206,15 +212,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
206
212
  requirements:
207
213
  - - ">="
208
214
  - !ruby/object:Gem::Version
209
- version: '2.6'
215
+ version: '2.7'
210
216
  required_rubygems_version: !ruby/object:Gem::Requirement
211
217
  requirements:
212
218
  - - ">="
213
219
  - !ruby/object:Gem::Version
214
220
  version: '0'
215
221
  requirements: []
216
- rubygems_version: 3.1.4
217
- signing_key:
222
+ rubygems_version: 3.4.1
223
+ signing_key:
218
224
  specification_version: 4
219
225
  summary: A library for specifying and validating data structures.
220
226
  test_files: []