dry-struct 1.6.0 → 1.8.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/CHANGELOG.md +76 -0
- data/LICENSE +1 -1
- data/README.md +4 -12
- data/dry-struct.gemspec +10 -14
- data/lib/dry/struct/class_interface.rb +40 -62
- data/lib/dry/struct/errors.rb +3 -3
- data/lib/dry/struct/extensions/pretty_print.rb +1 -1
- data/lib/dry/struct/extensions/super_diff.rb +10 -0
- data/lib/dry/struct/extensions.rb +4 -0
- data/lib/dry/struct/hashify.rb +3 -3
- data/lib/dry/struct/struct_builder.rb +3 -9
- data/lib/dry/struct/sum.rb +3 -5
- data/lib/dry/struct/value.rb +1 -3
- data/lib/dry/struct/version.rb +1 -1
- data/lib/dry/struct.rb +9 -5
- metadata +19 -79
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca7dd75ba219a6860a4532f8ede515b598b70e32ef8f0e07d4f42d99ea429111
|
4
|
+
data.tar.gz: 37c2870ddde97c4da85845f2f5118c13443eb9dcec600588542bab6ef7a8960e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9848e0d45c5031418374744045f6866d5a991398376f17524d8326b41abd22b9109f0476d641a680cd5f5acab76d5493262d40cae335dc0ee7864f7958080992
|
7
|
+
data.tar.gz: 974e9069e93e5a16d57fe5f9744ba24339fa0a30d26487d5f2ade5a0a7ae07c79d995160f380e45838b83b8e4851e52c4705c7d7cea9634ab4404a8816ebf6da
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,81 @@
|
|
1
1
|
<!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
|
2
2
|
|
3
|
+
## 1.8.0 2025-03-09
|
4
|
+
|
5
|
+
|
6
|
+
### Added
|
7
|
+
|
8
|
+
- Added super_diff extension for improved struct diffing in RSpec tests (@flash-gordon in #197)
|
9
|
+
|
10
|
+
Add this to your Gemfile:
|
11
|
+
```ruby
|
12
|
+
gem 'super_diff', group: :test
|
13
|
+
```
|
14
|
+
|
15
|
+
Then activate the extension in your spec_helper:
|
16
|
+
```ruby
|
17
|
+
Dry::Struct.load_extensions(:super_diff)
|
18
|
+
```
|
19
|
+
|
20
|
+
Now this
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
expected: #<Test::User name="Jane" age=22>
|
24
|
+
got: #<Test::User name="Jane" age=21>
|
25
|
+
|
26
|
+
(compared using eql?)
|
27
|
+
|
28
|
+
Diff:
|
29
|
+
@@ -1 +1 @@
|
30
|
+
-#<Test::User name="Jane" age=22>
|
31
|
+
+#<Test::User name="Jane" age=21>
|
32
|
+
```
|
33
|
+
|
34
|
+
will become this:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
expected: #<Test::User name: "Jane", age: 22>
|
38
|
+
got: #<Test::User name: "Jane", age: 21>
|
39
|
+
|
40
|
+
(compared using eql?)
|
41
|
+
|
42
|
+
#<Test::User {
|
43
|
+
name: "Jane",
|
44
|
+
- age: 22
|
45
|
+
+ age: 21
|
46
|
+
}>
|
47
|
+
```
|
48
|
+
|
49
|
+
|
50
|
+
[Compare v1.7.1...v1.8.0](https://github.com/dry-rb/dry-struct/compare/v1.7.1...v1.8.0)
|
51
|
+
|
52
|
+
## 1.7.1 2025-01-31
|
53
|
+
|
54
|
+
|
55
|
+
### Fixed
|
56
|
+
|
57
|
+
- Syntax errors on 3.3.0 (@flash-gordon, see https://github.com/dry-rb/dry-types/issues/478)
|
58
|
+
|
59
|
+
|
60
|
+
[Compare v1.7.0...v1.7.1](https://github.com/dry-rb/dry-struct/compare/v1.7.0...v1.7.1)
|
61
|
+
|
62
|
+
## 1.7.0 2025-01-06
|
63
|
+
|
64
|
+
|
65
|
+
### Fixed
|
66
|
+
|
67
|
+
- Fixed coercion errors for structs (issue #192 via #193) (@flash-gordon)
|
68
|
+
- Invalid method names are now allowed as struct attributes (issue #169 via #195) (@flash-gordon)
|
69
|
+
|
70
|
+
### Changed
|
71
|
+
|
72
|
+
- Missing attribute error now includes the name of the class (issue #170 via #191) (@phillipoertel + @cllns)
|
73
|
+
- 3.1 is now the minimum Ruby version (@flash-gordon)
|
74
|
+
- `Dry::Struct::Error` is now a subclass of `Dry::Types::CoercionError` (in #193) (@flash-gordon)
|
75
|
+
- `Dry::Struct#[]` now returns `nil` if an optional attribute is not set. This is consistent with calling accessor methods for optional attributes. (issue #171 via #194) (@ivleonov + @flash-gordon)
|
76
|
+
|
77
|
+
[Compare v1.6.0...v1.7.0](https://github.com/dry-rb/dry-struct/compare/v1.6.0...v1.7.0)
|
78
|
+
|
3
79
|
## 1.6.0 2022-11-04
|
4
80
|
|
5
81
|
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,29 +1,21 @@
|
|
1
1
|
<!--- this file is synced from dry-rb/template-gem project -->
|
2
2
|
[gem]: https://rubygems.org/gems/dry-struct
|
3
3
|
[actions]: https://github.com/dry-rb/dry-struct/actions
|
4
|
-
[codacy]: https://www.codacy.com/gh/dry-rb/dry-struct
|
5
|
-
[chat]: https://dry-rb.zulipchat.com
|
6
|
-
[inchpages]: http://inch-ci.org/github/dry-rb/dry-struct
|
7
4
|
|
8
|
-
# dry-struct [][gem]
|
11
|
-
[][actions]
|
12
|
-
[][codacy]
|
13
|
-
[][codacy]
|
14
|
-
[][inchpages]
|
5
|
+
# dry-struct [][gem] [][actions]
|
15
6
|
|
16
7
|
## Links
|
17
8
|
|
18
9
|
* [User documentation](https://dry-rb.org/gems/dry-struct)
|
19
10
|
* [API documentation](http://rubydoc.info/gems/dry-struct)
|
11
|
+
* [Forum](https://discourse.dry-rb.org)
|
20
12
|
|
21
13
|
## Supported Ruby versions
|
22
14
|
|
23
15
|
This library officially supports the following Ruby versions:
|
24
16
|
|
25
|
-
* MRI `>=
|
26
|
-
* jruby `>= 9.
|
17
|
+
* MRI `>= 3.1`
|
18
|
+
* jruby `>= 9.4` (not tested on CI)
|
27
19
|
|
28
20
|
## License
|
29
21
|
|
data/dry-struct.gemspec
CHANGED
@@ -21,21 +21,17 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.executables = []
|
22
22
|
spec.require_paths = ["lib"]
|
23
23
|
|
24
|
-
spec.metadata["allowed_push_host"]
|
25
|
-
spec.metadata["changelog_uri"]
|
26
|
-
spec.metadata["source_code_uri"]
|
27
|
-
spec.metadata["bug_tracker_uri"]
|
24
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
25
|
+
spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-struct/blob/main/CHANGELOG.md"
|
26
|
+
spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-struct"
|
27
|
+
spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-struct/issues"
|
28
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
28
29
|
|
29
|
-
spec.required_ruby_version = ">=
|
30
|
+
spec.required_ruby_version = ">= 3.1.0"
|
30
31
|
|
31
32
|
# to update dependencies edit project.yml
|
32
|
-
spec.
|
33
|
-
spec.
|
34
|
-
spec.
|
35
|
-
spec.
|
36
|
-
|
37
|
-
spec.add_development_dependency "bundler"
|
38
|
-
spec.add_development_dependency "rake"
|
39
|
-
spec.add_development_dependency "rspec"
|
40
|
-
spec.add_development_dependency "yard"
|
33
|
+
spec.add_dependency "dry-core", "~> 1.1"
|
34
|
+
spec.add_dependency "dry-types", "~> 1.8", ">= 1.8.2"
|
35
|
+
spec.add_dependency "ice_nine", "~> 0.11"
|
36
|
+
spec.add_dependency "zeitwerk", "~> 2.6"
|
41
37
|
end
|
@@ -11,15 +11,6 @@ module Dry
|
|
11
11
|
include Types::Type
|
12
12
|
include Types::Builder
|
13
13
|
|
14
|
-
# @param [Class] klass
|
15
|
-
def inherited(klass)
|
16
|
-
super
|
17
|
-
|
18
|
-
unless klass.name.eql?("Dry::Struct::Value")
|
19
|
-
klass.extend(Core::DescendantsTracker)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
14
|
# Adds an attribute for this {Struct} with given `name` and `type`
|
24
15
|
# and modifies {.schema} accordingly.
|
25
16
|
#
|
@@ -92,8 +83,8 @@ module Dry
|
|
92
83
|
# ruby.celebrities[0].pseudonym #=> 'Matz'
|
93
84
|
# ruby.celebrities[1].name #=> 'Aaron Patterson'
|
94
85
|
# ruby.celebrities[1].pseudonym #=> 'tenderlove'
|
95
|
-
def attribute(name, type = Undefined, &
|
96
|
-
attributes(name => build_type(name, type, &
|
86
|
+
def attribute(name, type = Undefined, &)
|
87
|
+
attributes(name => build_type(name, type, &))
|
97
88
|
end
|
98
89
|
|
99
90
|
# Add atributes from another struct
|
@@ -121,13 +112,13 @@ module Dry
|
|
121
112
|
#
|
122
113
|
# @param struct [Dry::Struct]
|
123
114
|
def attributes_from(struct)
|
124
|
-
extracted_schema = struct.schema.keys.
|
115
|
+
extracted_schema = struct.schema.keys.to_h do |key|
|
125
116
|
if key.required?
|
126
117
|
[key.name, key.type]
|
127
118
|
else
|
128
119
|
[:"#{key.name}?", key.type]
|
129
120
|
end
|
130
|
-
|
121
|
+
end
|
131
122
|
attributes(extracted_schema)
|
132
123
|
end
|
133
124
|
|
@@ -145,10 +136,10 @@ module Dry
|
|
145
136
|
# @param [Dry::Types::Type, nil] type or superclass of nested type
|
146
137
|
# @return [Dry::Struct]
|
147
138
|
#
|
148
|
-
def attribute?(*args, &
|
149
|
-
if args.size == 1 &&
|
139
|
+
def attribute?(*args, &)
|
140
|
+
if args.size == 1 && !block_given?
|
150
141
|
Core::Deprecations.warn(
|
151
|
-
"Dry::Struct.attribute? is deprecated for checking attribute presence, "\
|
142
|
+
"Dry::Struct.attribute? is deprecated for checking attribute presence, " \
|
152
143
|
"use has_attribute? instead",
|
153
144
|
tag: :"dry-struct"
|
154
145
|
)
|
@@ -157,7 +148,7 @@ module Dry
|
|
157
148
|
else
|
158
149
|
name, * = args
|
159
150
|
|
160
|
-
attribute(:"#{name}?", build_type(*args, &
|
151
|
+
attribute(:"#{name}?", build_type(*args, &))
|
161
152
|
end
|
162
153
|
end
|
163
154
|
|
@@ -189,8 +180,7 @@ module Dry
|
|
189
180
|
|
190
181
|
@attribute_names = nil
|
191
182
|
|
192
|
-
|
193
|
-
direct_descendants.each do |d|
|
183
|
+
subclasses.each do |d|
|
194
184
|
inherited_attrs = new_schema.reject { |k, _| d.has_attribute?(k.to_s.chomp("?").to_sym) }
|
195
185
|
d.attributes(inherited_attrs)
|
196
186
|
end
|
@@ -246,7 +236,7 @@ module Dry
|
|
246
236
|
|
247
237
|
# @param [Hash{Symbol => Object},Dry::Struct] attributes
|
248
238
|
# @raise [Struct::Error] if the given attributes don't conform {#schema}
|
249
|
-
def new(attributes = default_attributes, safe = false, &
|
239
|
+
def new(attributes = default_attributes, safe = false, &) # rubocop:disable Style/OptionalBooleanParameter
|
250
240
|
if attributes.is_a?(Struct)
|
251
241
|
if equal?(attributes.class)
|
252
242
|
attributes
|
@@ -256,7 +246,7 @@ module Dry
|
|
256
246
|
# User.new(super_user)
|
257
247
|
#
|
258
248
|
# We may deprecate this behavior in future forcing people to be explicit
|
259
|
-
new(attributes.to_h, safe, &
|
249
|
+
new(attributes.to_h, safe, &)
|
260
250
|
end
|
261
251
|
elsif safe
|
262
252
|
load(schema.call_safe(attributes) { |output = attributes| return yield output })
|
@@ -268,11 +258,11 @@ module Dry
|
|
268
258
|
end
|
269
259
|
|
270
260
|
# @api private
|
271
|
-
def call_safe(input, &
|
261
|
+
def call_safe(input, &)
|
272
262
|
if input.is_a?(self)
|
273
263
|
input
|
274
264
|
else
|
275
|
-
new(input, true, &
|
265
|
+
new(input, true, &)
|
276
266
|
end
|
277
267
|
end
|
278
268
|
|
@@ -323,48 +313,32 @@ module Dry
|
|
323
313
|
|
324
314
|
# @param [({Symbol => Object})] args
|
325
315
|
# @return [Dry::Types::Result::Success]
|
326
|
-
def success(*args)
|
327
|
-
result(Types::Result::Success, *args)
|
328
|
-
end
|
316
|
+
def success(*args) = result(Types::Result::Success, *args)
|
329
317
|
|
330
318
|
# @param [({Symbol => Object})] args
|
331
319
|
# @return [Dry::Types::Result::Failure]
|
332
|
-
def failure(*args)
|
333
|
-
result(Types::Result::Failure, *args)
|
334
|
-
end
|
320
|
+
def failure(*args) = result(Types::Result::Failure, *args)
|
335
321
|
|
336
322
|
# @param [Class] klass
|
337
323
|
# @param [({Symbol => Object})] args
|
338
|
-
def result(klass, *args)
|
339
|
-
klass.new(*args)
|
340
|
-
end
|
324
|
+
def result(klass, *args) = klass.new(*args)
|
341
325
|
|
342
326
|
# @return [false]
|
343
|
-
def default?
|
344
|
-
false
|
345
|
-
end
|
327
|
+
def default? = false
|
346
328
|
|
347
329
|
# @param [Object, Dry::Struct] other
|
348
330
|
# @return [Boolean]
|
349
|
-
def ===(other)
|
350
|
-
other.is_a?(self)
|
351
|
-
end
|
331
|
+
def ===(other) = other.is_a?(self)
|
352
332
|
alias_method :primitive?, :===
|
353
333
|
|
354
334
|
# @return [true]
|
355
|
-
def constrained?
|
356
|
-
true
|
357
|
-
end
|
335
|
+
def constrained? = true
|
358
336
|
|
359
337
|
# @return [self]
|
360
|
-
def primitive
|
361
|
-
self
|
362
|
-
end
|
338
|
+
def primitive = self
|
363
339
|
|
364
340
|
# @return [false]
|
365
|
-
def optional?
|
366
|
-
false
|
367
|
-
end
|
341
|
+
def optional? = false
|
368
342
|
|
369
343
|
# @return [Proc]
|
370
344
|
def to_proc
|
@@ -375,9 +349,7 @@ module Dry
|
|
375
349
|
#
|
376
350
|
# @param [Symbol] key Attribute name
|
377
351
|
# @return [Boolean]
|
378
|
-
def has_attribute?(key)
|
379
|
-
schema.key?(key)
|
380
|
-
end
|
352
|
+
def has_attribute?(key) = schema.key?(key)
|
381
353
|
|
382
354
|
# Gets the list of attribute names
|
383
355
|
#
|
@@ -455,11 +427,11 @@ module Dry
|
|
455
427
|
# Constructs a type
|
456
428
|
#
|
457
429
|
# @return [Dry::Types::Type, Dry::Struct]
|
458
|
-
def build_type(name, type = Undefined, &
|
430
|
+
def build_type(name, type = Undefined, &)
|
459
431
|
type_object =
|
460
432
|
if type.is_a?(::String)
|
461
433
|
Types[type]
|
462
|
-
elsif
|
434
|
+
elsif !block_given? && Undefined.equal?(type)
|
463
435
|
raise(
|
464
436
|
::ArgumentError,
|
465
437
|
"you must supply a type or a block to `Dry::Struct.attribute`"
|
@@ -468,26 +440,32 @@ module Dry
|
|
468
440
|
type
|
469
441
|
end
|
470
442
|
|
471
|
-
if
|
472
|
-
struct_builder.(name, type_object, &
|
443
|
+
if block_given?
|
444
|
+
struct_builder.(name, type_object, &)
|
473
445
|
else
|
474
446
|
type_object
|
475
447
|
end
|
476
448
|
end
|
477
449
|
private :build_type
|
478
450
|
|
451
|
+
# @api private
|
479
452
|
def define_accessors(keys)
|
480
|
-
keys.each do |key|
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
453
|
+
(keys - instance_methods).each do |key|
|
454
|
+
if valid_method_name?(key)
|
455
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
456
|
+
def #{key} # def email
|
457
|
+
@attributes[#{key.inspect}] # @attributes[:email]
|
458
|
+
end # end
|
459
|
+
RUBY
|
460
|
+
else
|
461
|
+
define_method(key) { @attributes[key] }
|
462
|
+
end
|
488
463
|
end
|
489
464
|
end
|
490
465
|
private :define_accessors
|
466
|
+
|
467
|
+
# @api private
|
468
|
+
private def valid_method_name?(key) = key.to_s.match?(/\A[a-zA-Z_]\w*\z/)
|
491
469
|
end
|
492
470
|
end
|
493
471
|
end
|
data/lib/dry/struct/errors.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module Dry
|
4
4
|
class Struct
|
5
5
|
# Raised when given input doesn't conform schema and constructor type
|
6
|
-
Error = Class.new(
|
6
|
+
Error = Class.new(::Dry::Types::CoercionError)
|
7
7
|
|
8
8
|
# Raised when defining duplicate attributes
|
9
9
|
class RepeatedAttributeError < ::ArgumentError
|
@@ -16,8 +16,8 @@ module Dry
|
|
16
16
|
|
17
17
|
# Raised when a struct doesn't have an attribute
|
18
18
|
class MissingAttributeError < ::KeyError
|
19
|
-
def initialize(
|
20
|
-
super("Missing attribute: #{
|
19
|
+
def initialize(attribute:, klass:)
|
20
|
+
super("Missing attribute: #{attribute.inspect} on #{klass}")
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
data/lib/dry/struct/hashify.rb
CHANGED
@@ -9,11 +9,11 @@ module Dry
|
|
9
9
|
# @return [Hash, Array]
|
10
10
|
def self.[](value)
|
11
11
|
if value.is_a?(Struct)
|
12
|
-
value.to_h.transform_values {
|
12
|
+
value.to_h.transform_values { self[_1] }
|
13
13
|
elsif value.respond_to?(:to_hash)
|
14
|
-
value.to_hash.transform_values {
|
14
|
+
value.to_hash.transform_values { self[_1] }
|
15
15
|
elsif value.respond_to?(:to_ary)
|
16
|
-
value.to_ary.map {
|
16
|
+
value.to_ary.map { self[_1] }
|
17
17
|
else
|
18
18
|
value
|
19
19
|
end
|
@@ -43,17 +43,13 @@ module Dry
|
|
43
43
|
|
44
44
|
private
|
45
45
|
|
46
|
-
def type?(type)
|
47
|
-
type.is_a?(Types::Type)
|
48
|
-
end
|
46
|
+
def type?(type) = type.is_a?(Types::Type)
|
49
47
|
|
50
48
|
def array?(type)
|
51
49
|
type?(type) && !type.optional? && type.primitive.equal?(::Array)
|
52
50
|
end
|
53
51
|
|
54
|
-
def optional?(type)
|
55
|
-
type?(type) && type.optional?
|
56
|
-
end
|
52
|
+
def optional?(type) = type?(type) && type.optional?
|
57
53
|
|
58
54
|
def parent(type)
|
59
55
|
if array?(type)
|
@@ -95,9 +91,7 @@ module Dry
|
|
95
91
|
visit(member)
|
96
92
|
end
|
97
93
|
|
98
|
-
def visit_nominal(*)
|
99
|
-
Undefined
|
100
|
-
end
|
94
|
+
def visit_nominal(*) = Undefined
|
101
95
|
|
102
96
|
def visit_constructor(node)
|
103
97
|
definition, * = node
|
data/lib/dry/struct/sum.rb
CHANGED
@@ -18,7 +18,7 @@ module Dry
|
|
18
18
|
# @return [Dry::Types::Result]
|
19
19
|
def try(input)
|
20
20
|
if input.is_a?(Struct)
|
21
|
-
try_struct(input) { super }
|
21
|
+
::Dry::Types::Result::Success.new(try_struct(input) { return super })
|
22
22
|
else
|
23
23
|
super
|
24
24
|
end
|
@@ -28,7 +28,7 @@ module Dry
|
|
28
28
|
# @param [Dry::Types::Type] type
|
29
29
|
# @return [Dry::Types::Sum]
|
30
30
|
def |(type)
|
31
|
-
if type.is_a?(Class) && type <= Struct || type.is_a?(Sum)
|
31
|
+
if (type.is_a?(::Class) && type <= Struct) || type.is_a?(Sum)
|
32
32
|
Sum.new(self, type)
|
33
33
|
else
|
34
34
|
super
|
@@ -36,9 +36,7 @@ module Dry
|
|
36
36
|
end
|
37
37
|
|
38
38
|
# @return [boolean]
|
39
|
-
def ===(value)
|
40
|
-
left === value || right === value
|
41
|
-
end
|
39
|
+
def ===(value) = left === value || right === value
|
42
40
|
|
43
41
|
protected
|
44
42
|
|
data/lib/dry/struct/value.rb
CHANGED
@@ -29,9 +29,7 @@ module Dry
|
|
29
29
|
# @param (see ClassInterface#new)
|
30
30
|
# @return [Value]
|
31
31
|
# @see https://github.com/dkubb/ice_nine
|
32
|
-
def self.new(*)
|
33
|
-
::IceNine.deep_freeze(super)
|
34
|
-
end
|
32
|
+
def self.new(*) = ::IceNine.deep_freeze(super)
|
35
33
|
end
|
36
34
|
|
37
35
|
deprecate_constant :Value
|
data/lib/dry/struct/version.rb
CHANGED
data/lib/dry/struct.rb
CHANGED
@@ -30,7 +30,7 @@ module Dry
|
|
30
30
|
def self.Struct(attributes = Dry::Core::Constants::EMPTY_HASH, &block)
|
31
31
|
Class.new(Dry::Struct) do
|
32
32
|
attributes.each { |a, type| attribute a, type }
|
33
|
-
module_eval(&block) if
|
33
|
+
module_eval(&block) if block_given?
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -145,7 +145,13 @@ module Dry
|
|
145
145
|
# rom_n_roda[:title] #=> 'Web Development with ROM and Roda'
|
146
146
|
# rom_n_roda[:subtitle] #=> nil
|
147
147
|
def [](name)
|
148
|
-
@attributes.fetch(name)
|
148
|
+
@attributes.fetch(name) do
|
149
|
+
if self.class.attribute_names.include?(name)
|
150
|
+
nil
|
151
|
+
else
|
152
|
+
raise MissingAttributeError.new(attribute: name, klass: self.class)
|
153
|
+
end
|
154
|
+
end
|
149
155
|
end
|
150
156
|
|
151
157
|
# Converts the {Dry::Struct} to a hash with keys representing
|
@@ -215,9 +221,7 @@ module Dry
|
|
215
221
|
# Pattern matching support
|
216
222
|
#
|
217
223
|
# @api private
|
218
|
-
def deconstruct_keys(_keys)
|
219
|
-
attributes
|
220
|
-
end
|
224
|
+
def deconstruct_keys(_keys) = attributes
|
221
225
|
end
|
222
226
|
end
|
223
227
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-struct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-core
|
@@ -16,40 +16,34 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '2'
|
19
|
+
version: '1.1'
|
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.
|
30
|
-
- - "<"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '2'
|
26
|
+
version: '1.1'
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: dry-types
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
36
30
|
requirements:
|
37
|
-
- - "
|
31
|
+
- - "~>"
|
38
32
|
- !ruby/object:Gem::Version
|
39
|
-
version: '1.
|
40
|
-
- - "
|
33
|
+
version: '1.8'
|
34
|
+
- - ">="
|
41
35
|
- !ruby/object:Gem::Version
|
42
|
-
version:
|
36
|
+
version: 1.8.2
|
43
37
|
type: :runtime
|
44
38
|
prerelease: false
|
45
39
|
version_requirements: !ruby/object:Gem::Requirement
|
46
40
|
requirements:
|
47
|
-
- - "
|
41
|
+
- - "~>"
|
48
42
|
- !ruby/object:Gem::Version
|
49
|
-
version: '1.
|
50
|
-
- - "
|
43
|
+
version: '1.8'
|
44
|
+
- - ">="
|
51
45
|
- !ruby/object:Gem::Version
|
52
|
-
version:
|
46
|
+
version: 1.8.2
|
53
47
|
- !ruby/object:Gem::Dependency
|
54
48
|
name: ice_nine
|
55
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,62 +72,6 @@ dependencies:
|
|
78
72
|
- - "~>"
|
79
73
|
- !ruby/object:Gem::Version
|
80
74
|
version: '2.6'
|
81
|
-
- !ruby/object:Gem::Dependency
|
82
|
-
name: bundler
|
83
|
-
requirement: !ruby/object:Gem::Requirement
|
84
|
-
requirements:
|
85
|
-
- - ">="
|
86
|
-
- !ruby/object:Gem::Version
|
87
|
-
version: '0'
|
88
|
-
type: :development
|
89
|
-
prerelease: false
|
90
|
-
version_requirements: !ruby/object:Gem::Requirement
|
91
|
-
requirements:
|
92
|
-
- - ">="
|
93
|
-
- !ruby/object:Gem::Version
|
94
|
-
version: '0'
|
95
|
-
- !ruby/object:Gem::Dependency
|
96
|
-
name: rake
|
97
|
-
requirement: !ruby/object:Gem::Requirement
|
98
|
-
requirements:
|
99
|
-
- - ">="
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
version: '0'
|
102
|
-
type: :development
|
103
|
-
prerelease: false
|
104
|
-
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
requirements:
|
106
|
-
- - ">="
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
version: '0'
|
109
|
-
- !ruby/object:Gem::Dependency
|
110
|
-
name: rspec
|
111
|
-
requirement: !ruby/object:Gem::Requirement
|
112
|
-
requirements:
|
113
|
-
- - ">="
|
114
|
-
- !ruby/object:Gem::Version
|
115
|
-
version: '0'
|
116
|
-
type: :development
|
117
|
-
prerelease: false
|
118
|
-
version_requirements: !ruby/object:Gem::Requirement
|
119
|
-
requirements:
|
120
|
-
- - ">="
|
121
|
-
- !ruby/object:Gem::Version
|
122
|
-
version: '0'
|
123
|
-
- !ruby/object:Gem::Dependency
|
124
|
-
name: yard
|
125
|
-
requirement: !ruby/object:Gem::Requirement
|
126
|
-
requirements:
|
127
|
-
- - ">="
|
128
|
-
- !ruby/object:Gem::Version
|
129
|
-
version: '0'
|
130
|
-
type: :development
|
131
|
-
prerelease: false
|
132
|
-
version_requirements: !ruby/object:Gem::Requirement
|
133
|
-
requirements:
|
134
|
-
- - ">="
|
135
|
-
- !ruby/object:Gem::Version
|
136
|
-
version: '0'
|
137
75
|
description: Typed structs and value objects
|
138
76
|
email:
|
139
77
|
- piotr.solnica@gmail.com
|
@@ -153,6 +91,7 @@ files:
|
|
153
91
|
- lib/dry/struct/errors.rb
|
154
92
|
- lib/dry/struct/extensions.rb
|
155
93
|
- lib/dry/struct/extensions/pretty_print.rb
|
94
|
+
- lib/dry/struct/extensions/super_diff.rb
|
156
95
|
- lib/dry/struct/hashify.rb
|
157
96
|
- lib/dry/struct/printer.rb
|
158
97
|
- lib/dry/struct/struct_builder.rb
|
@@ -167,7 +106,8 @@ metadata:
|
|
167
106
|
changelog_uri: https://github.com/dry-rb/dry-struct/blob/main/CHANGELOG.md
|
168
107
|
source_code_uri: https://github.com/dry-rb/dry-struct
|
169
108
|
bug_tracker_uri: https://github.com/dry-rb/dry-struct/issues
|
170
|
-
|
109
|
+
rubygems_mfa_required: 'true'
|
110
|
+
post_install_message:
|
171
111
|
rdoc_options: []
|
172
112
|
require_paths:
|
173
113
|
- lib
|
@@ -175,15 +115,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
175
115
|
requirements:
|
176
116
|
- - ">="
|
177
117
|
- !ruby/object:Gem::Version
|
178
|
-
version:
|
118
|
+
version: 3.1.0
|
179
119
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
180
120
|
requirements:
|
181
121
|
- - ">="
|
182
122
|
- !ruby/object:Gem::Version
|
183
123
|
version: '0'
|
184
124
|
requirements: []
|
185
|
-
rubygems_version: 3.
|
186
|
-
signing_key:
|
125
|
+
rubygems_version: 3.3.27
|
126
|
+
signing_key:
|
187
127
|
specification_version: 4
|
188
128
|
summary: Typed structs and value objects
|
189
129
|
test_files: []
|