stannum 0.2.0 → 0.4.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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +49 -0
  3. data/README.md +130 -1200
  4. data/config/locales/en.rb +4 -0
  5. data/lib/stannum/association.rb +293 -0
  6. data/lib/stannum/associations/many.rb +250 -0
  7. data/lib/stannum/associations/one.rb +106 -0
  8. data/lib/stannum/associations.rb +11 -0
  9. data/lib/stannum/attribute.rb +86 -8
  10. data/lib/stannum/constraints/base.rb +3 -5
  11. data/lib/stannum/constraints/enum.rb +1 -1
  12. data/lib/stannum/constraints/equality.rb +1 -1
  13. data/lib/stannum/constraints/format.rb +72 -0
  14. data/lib/stannum/constraints/hashes/extra_keys.rb +13 -13
  15. data/lib/stannum/constraints/hashes/indifferent_extra_keys.rb +47 -0
  16. data/lib/stannum/constraints/hashes.rb +6 -2
  17. data/lib/stannum/constraints/identity.rb +1 -1
  18. data/lib/stannum/constraints/properties/base.rb +124 -0
  19. data/lib/stannum/constraints/properties/do_not_match_property.rb +117 -0
  20. data/lib/stannum/constraints/properties/match_property.rb +117 -0
  21. data/lib/stannum/constraints/properties/matching.rb +112 -0
  22. data/lib/stannum/constraints/properties.rb +17 -0
  23. data/lib/stannum/constraints/signature.rb +2 -2
  24. data/lib/stannum/constraints/tuples/extra_items.rb +6 -6
  25. data/lib/stannum/constraints/type.rb +4 -4
  26. data/lib/stannum/constraints/types/array_type.rb +2 -2
  27. data/lib/stannum/constraints/types/hash_type.rb +4 -4
  28. data/lib/stannum/constraints/union.rb +1 -1
  29. data/lib/stannum/constraints/uuid.rb +30 -0
  30. data/lib/stannum/constraints.rb +3 -0
  31. data/lib/stannum/contract.rb +7 -7
  32. data/lib/stannum/contracts/array_contract.rb +2 -7
  33. data/lib/stannum/contracts/base.rb +15 -15
  34. data/lib/stannum/contracts/builder.rb +15 -4
  35. data/lib/stannum/contracts/hash_contract.rb +3 -9
  36. data/lib/stannum/contracts/indifferent_hash_contract.rb +15 -2
  37. data/lib/stannum/contracts/map_contract.rb +6 -10
  38. data/lib/stannum/contracts/parameters/arguments_contract.rb +1 -1
  39. data/lib/stannum/contracts/parameters/keywords_contract.rb +1 -1
  40. data/lib/stannum/contracts/parameters/signature_contract.rb +1 -1
  41. data/lib/stannum/contracts/parameters_contract.rb +4 -4
  42. data/lib/stannum/contracts/tuple_contract.rb +6 -6
  43. data/lib/stannum/entities/associations.rb +451 -0
  44. data/lib/stannum/entities/attributes.rb +316 -0
  45. data/lib/stannum/entities/constraints.rb +178 -0
  46. data/lib/stannum/entities/primary_key.rb +148 -0
  47. data/lib/stannum/entities/properties.rb +208 -0
  48. data/lib/stannum/entities.rb +16 -0
  49. data/lib/stannum/entity.rb +87 -0
  50. data/lib/stannum/errors.rb +12 -16
  51. data/lib/stannum/messages/default_strategy.rb +2 -2
  52. data/lib/stannum/parameter_validation.rb +10 -10
  53. data/lib/stannum/rspec/match_errors_matcher.rb +7 -7
  54. data/lib/stannum/rspec/validate_parameter.rb +2 -2
  55. data/lib/stannum/rspec/validate_parameter_matcher.rb +22 -20
  56. data/lib/stannum/schema.rb +117 -76
  57. data/lib/stannum/struct.rb +12 -346
  58. data/lib/stannum/support/optional.rb +1 -1
  59. data/lib/stannum/version.rb +4 -4
  60. data/lib/stannum.rb +6 -0
  61. metadata +26 -85
@@ -2,130 +2,171 @@
2
2
 
3
3
  require 'forwardable'
4
4
 
5
- require 'stannum/attribute'
6
-
7
5
  module Stannum
8
- # Abstract class for defining attribute methods for a struct.
6
+ # Abstract class for defining property methods for an entity.
9
7
  #
10
8
  # @see Stannum::Attribute.
11
9
  class Schema < Module
12
10
  extend Forwardable
13
11
  include Enumerable
14
12
 
15
- def initialize
16
- super
13
+ # @param property_class [Class] the class representing the elements of the
14
+ # schema.
15
+ # @param property_name [String, Symbol] the name of the schema elements.
16
+ def initialize(property_class:, property_name:)
17
+ super()
18
+
19
+ tools.assertions.validate_class(property_class, as: 'property class')
20
+ tools.assertions.validate_name(property_name, as: 'property name')
17
21
 
18
- @attributes = {}
22
+ @properties = {}
23
+ @property_class = property_class
24
+ @property_name = property_name.to_s
19
25
  end
20
26
 
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.
27
+ # @return [Class] the class representing the elements of the schema.
28
+ attr_reader :property_class
26
29
 
27
- # @!method each_key
28
- # Iterates through the the attributes by name.
29
- #
30
- # @yieldparam name [String] The name of the attribute.
30
+ # @return [String] the name of the schema elements.
31
+ attr_reader :property_name
31
32
 
32
- # @!method each_value
33
- # Iterates through the the attributes by attribute object.
33
+ # Retrieves the named property object.
34
34
  #
35
- # @yieldparam attribute [Stannum::Attribute] The attribute object.
36
-
37
- def_delegators :attributes,
38
- :each,
39
- :each_key,
40
- :each_value
41
-
42
- # Retrieves the named attribute object.
35
+ # @param key [String, Symbol] The name of the requested property.
43
36
  #
44
- # @param key [String, Symbol] The name of the requested attribute.
45
- #
46
- # @return [Stannum::Attribute] The attribute object.
37
+ # @return [Stannum::Attribute] The property object.
47
38
  #
48
39
  # @raise ArgumentError if the key is invalid.
49
- # @raise KeyError if the attribute is not defined.
40
+ # @raise KeyError if the property is not defined.
50
41
  def [](key)
51
- validate_key(key)
42
+ tools.assertions.assert_name(key, as: 'key', error_class: ArgumentError)
52
43
 
53
- attributes.fetch(key.to_s)
54
- end
44
+ str = -key.to_s
45
+
46
+ each_ancestor do |ancestor|
47
+ next unless ancestor.own_properties.key?(str)
48
+
49
+ return ancestor.own_properties[str]
50
+ end
55
51
 
56
- # rubocop:disable Metrics/MethodLength
52
+ {}.fetch(str)
53
+ end
57
54
 
58
55
  # @api private
59
56
  #
60
- # Defines an attribute and adds the attribute to the contract.
57
+ # Defines an property and adds the property to the contract.
61
58
  #
62
- # This method should not be called directly. Instead, define attributes via
63
- # the Struct.attribute class method.
59
+ # This method should not be called directly. Instead, define properties via
60
+ # the Struct.property class method.
64
61
  #
65
62
  # @see Stannum::Struct
66
- def define_attribute(name:, options:, type:)
67
- attribute = Stannum::Attribute.new(
68
- name: name,
69
- options: options,
70
- type: type
71
- )
72
-
73
- if @attributes.key?(attribute.name)
74
- raise ArgumentError, "attribute #{name.inspect} already exists"
63
+ def define(name:, options:, type:, definition_class: nil)
64
+ definition_class ||= property_class
65
+
66
+ property = definition_class.new(name:, options:, type:)
67
+
68
+ if @properties.key?(property.name)
69
+ message =
70
+ "#{tools.str.singularize(property_name)} #{name.inspect} " \
71
+ 'already exists'
72
+
73
+ raise ArgumentError, message
75
74
  end
76
75
 
77
- define_reader(attribute.name, attribute.reader_name)
78
- define_writer(attribute.name, attribute.writer_name, attribute.default)
76
+ definition_class::Builder.new(self).call(property)
79
77
 
80
- @attributes[attribute.name] = attribute
78
+ @properties[property.name] = property
81
79
  end
82
- # rubocop:enable Metrics/MethodLength
83
80
 
84
- # Checks if the given attribute is defined.
81
+ # Iterates through the the properties by name and property object.
85
82
  #
86
- # @param key [String, Symbol] the name of the attribute to check.
83
+ # @yieldparam name [String] The name of the property.
84
+ # @yieldparam property [Stannum::Attribute] The property object.
85
+ def each(&block)
86
+ return enum_for(:each) { size } unless block_given?
87
+
88
+ each_ancestor do |ancestor|
89
+ ancestor.own_properties.each(&block)
90
+ end
91
+ end
92
+
93
+ # Iterates through the the properties by name.
87
94
  #
88
- # @return [Boolean] true if the attribute is defined; otherwise false.
89
- def key?(key)
90
- validate_key(key)
95
+ # @yieldparam name [String] The name of the property.
96
+ def each_key(&block)
97
+ return enum_for(:each_key) { size } unless block_given?
91
98
 
92
- attributes.key?(key.to_s)
99
+ each_ancestor do |ancestor|
100
+ ancestor.own_properties.each_key(&block)
101
+ end
93
102
  end
94
- alias has_key? key?
95
103
 
96
- # @private
97
- def own_attributes
98
- @attributes
104
+ # Iterates through the the properties by property object.
105
+ #
106
+ # @yieldparam property [Stannum::Attribute] The property object.
107
+ def each_value(&block)
108
+ return enum_for(:each_value) { size } unless block_given?
109
+
110
+ each_ancestor do |ancestor|
111
+ ancestor.own_properties.each_value(&block)
112
+ end
99
113
  end
100
114
 
101
- private
115
+ # Checks if the given property is defined.
116
+ #
117
+ # @param key [String, Symbol] the name of the property to check.
118
+ #
119
+ # @return [Boolean] true if the property is defined; otherwise false.
120
+ def key?(key)
121
+ tools.assertions.assert_name(key, as: 'key', error_class: ArgumentError)
102
122
 
103
- def attributes
104
- ancestors
105
- .reverse_each
106
- .select { |mod| mod.is_a?(Stannum::Schema) }
107
- .map(&:own_attributes)
108
- .reduce(&:merge)
123
+ each_ancestor.any? do |ancestor|
124
+ ancestor.own_properties.key?(key.to_s)
125
+ end
109
126
  end
127
+ alias has_key? key?
110
128
 
111
- def define_reader(attr_name, reader_name)
112
- define_method(reader_name) { @attributes[attr_name] }
129
+ # Returns the defined property keys.
130
+ #
131
+ # @return [Array<String>] the property keys.
132
+ def keys
133
+ each_key.to_a
113
134
  end
114
135
 
115
- def define_writer(attr_name, writer_name, default_value)
116
- define_method(writer_name) do |value|
117
- @attributes[attr_name] = value.nil? ? default_value : value
136
+ # @private
137
+ def own_properties
138
+ @properties
139
+ end
140
+
141
+ # @return [Integer] the number of defined properties.
142
+ def size
143
+ each_ancestor.reduce(0) do |memo, ancestor|
144
+ memo + ancestor.own_properties.size
118
145
  end
119
146
  end
147
+ alias count size
148
+
149
+ # Returns the defined property value.
150
+ #
151
+ # @return [Array<Stannum::Attribute>] the property values.
152
+ def values
153
+ each_value.to_a
154
+ end
155
+
156
+ private
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
@@ -20,7 +20,7 @@ module Stannum::Support
20
20
 
21
21
  options.merge(
22
22
  required: required?(
23
- default: default,
23
+ default:,
24
24
  optional: validate_option(optional, as: :optional),
25
25
  required: validate_option(required, as: :required)
26
26
  )
@@ -10,7 +10,7 @@ module Stannum
10
10
  # Major version.
11
11
  MAJOR = 0
12
12
  # Minor version.
13
- MINOR = 2
13
+ MINOR = 4
14
14
  # Patch version.
15
15
  PATCH = 0
16
16
  # Prerelease version.
@@ -27,13 +27,13 @@ module Stannum
27
27
  #
28
28
  # @see SleepingKingStudios::Tools::SemanticVersion#to_gem_version
29
29
  def to_gem_version
30
- str = +"#{MAJOR}.#{MINOR}.#{PATCH}"
30
+ str = "#{MAJOR}.#{MINOR}.#{PATCH}"
31
31
 
32
32
  prerelease = value_of(:PRERELEASE)
33
- str << ".#{prerelease}" if prerelease
33
+ str = "#{str}.#{prerelease}" if prerelease
34
34
 
35
35
  build = value_of(:BUILD)
36
- str << ".#{build}" if build
36
+ str = "#{str}.#{build}" if build
37
37
 
38
38
  str
39
39
  end
data/lib/stannum.rb CHANGED
@@ -4,13 +4,19 @@ require 'stannum/version'
4
4
 
5
5
  # A library for specifying and validating data structures.
6
6
  module Stannum
7
+ autoload :Association, 'stannum/association'
8
+ autoload :Associations, 'stannum/associations'
9
+ autoload :Attribute, 'stannum/attribute'
7
10
  autoload :Constraint, 'stannum/constraint'
8
11
  autoload :Constraints, 'stannum/constraints'
9
12
  autoload :Contract, 'stannum/contract'
10
13
  autoload :Contracts, 'stannum/contracts'
14
+ autoload :Entities, 'stannum/entities'
15
+ autoload :Entity, 'stannum/entity'
11
16
  autoload :Errors, 'stannum/errors'
12
17
  autoload :Messages, 'stannum/messages'
13
18
  autoload :ParameterValidation, 'stannum/parameter_validation'
19
+ autoload :Schema, 'stannum/schema'
14
20
  autoload :Struct, 'stannum/struct'
15
21
 
16
22
  # @return [String] the absolute path to the gem directory.