dry-struct 0.7.0 → 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/.travis.yml +3 -3
- data/CHANGELOG.md +17 -0
- data/Gemfile +2 -1
- data/README.md +2 -2
- data/benchmarks/basic.rb +1 -1
- data/benchmarks/constrained.rb +2 -2
- data/benchmarks/profile_instantiation.rb +19 -0
- data/benchmarks/setup.rb +11 -0
- data/dry-struct.gemspec +2 -2
- data/lib/dry/struct.rb +1 -0
- data/lib/dry/struct/class_interface.rb +37 -22
- data/lib/dry/struct/printer.rb +18 -0
- data/lib/dry/struct/sum.rb +12 -1
- data/lib/dry/struct/version.rb +1 -1
- metadata +9 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b8e3499eadacef74b5203366275c7f68c77ad138e950ac4e5f0a02635bc118f9
|
|
4
|
+
data.tar.gz: a227f8eb3d8beb3b1388bbe1d447055076938611929ed0a41610253feae64741
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1c721723926e9edaf876e0e96e209fbdd33b882a9f92b2b670aeb3af26901c9c42d262a7446e811706c4fe02a3eb4bf76895747c2cac084ad20023952f480879
|
|
7
|
+
data.tar.gz: a0dba3a720335d985feea9004a0b1ec1f8bb8625a4b6947a22acb6ab68bb0f4fb23aea38c8122570475ed332dc408330391d1572707216007f302e853e8a6e66
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
# 1.0.0 2019-04-23
|
|
2
|
+
|
|
3
|
+
## Changed
|
|
4
|
+
|
|
5
|
+
* `valid?` and `===` behave differently, `===` works the same way `Class#===` does and `valid?` checks if the value _can be_ coerced to the struct (flash-gordon)
|
|
6
|
+
|
|
7
|
+
## Added
|
|
8
|
+
|
|
9
|
+
* `Struct.call` now accepts an optional block that will be called on failed coercion. This behavior is consistent with dry-types 1.0. Note that `.new` doesn't take a block (flash-gordon)
|
|
10
|
+
```ruby
|
|
11
|
+
User = Dry::Struct(name: 'string')
|
|
12
|
+
User.(1) { :oh_no }
|
|
13
|
+
# => :oh_no
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
[Compare v0.7.0...v1.0.0](https://github.com/dry-rb/dry-struct/compare/v0.7.0...v1.0.0)
|
|
17
|
+
|
|
1
18
|
# 0.7.0 2019-03-22
|
|
2
19
|
|
|
3
20
|
## Changed
|
data/Gemfile
CHANGED
|
@@ -7,7 +7,7 @@ gemspec
|
|
|
7
7
|
group :test do
|
|
8
8
|
gem 'codeclimate-test-reporter', platform: :mri, require: false
|
|
9
9
|
gem 'simplecov', require: false
|
|
10
|
-
gem 'warning'
|
|
10
|
+
gem 'warning'
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
group :tools do
|
|
@@ -22,4 +22,5 @@ group :benchmarks do
|
|
|
22
22
|
gem 'virtus'
|
|
23
23
|
gem 'fast_attributes'
|
|
24
24
|
gem 'attrio'
|
|
25
|
+
gem 'hotch'
|
|
25
26
|
end
|
data/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[gem]: https://rubygems.org/gems/dry-struct
|
|
2
2
|
[travis]: https://travis-ci.org/dry-rb/dry-struct
|
|
3
3
|
[codeclimate]: https://codeclimate.com/github/dry-rb/dry-struct
|
|
4
|
-
[coveralls]: https://coveralls.io/r/dry-rb/dry-struct
|
|
5
4
|
[inchpages]: http://inch-ci.org/github/dry-rb/dry-struct
|
|
5
|
+
[chat]: https://dry-rb.zulipchat.com
|
|
6
6
|
|
|
7
|
-
# dry-struct [][chat]
|
|
8
8
|
|
|
9
9
|
[][gem]
|
|
10
10
|
[][travis]
|
data/benchmarks/basic.rb
CHANGED
data/benchmarks/constrained.rb
CHANGED
|
@@ -21,9 +21,9 @@ module Types
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
class DryStructUser < Dry::Struct
|
|
24
|
-
attribute :id, Types::
|
|
24
|
+
attribute :id, Types::Params::Integer
|
|
25
25
|
attribute :name, Types::Strict::String.constrained(size: 3..64)
|
|
26
|
-
attribute :age, Types::
|
|
26
|
+
attribute :age, Types::Params::Integer.constrained(gt: 18)
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
puts ARUser.new(id: 1, name: 'Jane', age: '21').inspect
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require_relative 'setup'
|
|
2
|
+
|
|
3
|
+
ATTR_NAMES = [:attr0, :attr1, :attr2, :attr3, :attr4, :attr5, :attr6, :attr7, :attr8, :attr9]
|
|
4
|
+
|
|
5
|
+
class Integers < Dry::Struct
|
|
6
|
+
ATTR_NAMES.each do |name|
|
|
7
|
+
attribute? name, 'coercible.integer'
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
integers = {attr0: 0, attr1: 1, attr2: 2, attr3: 3, attr4: 4, attr5: 5, attr6: 6, attr7: 7, attr8: 8, attr9: 9}
|
|
12
|
+
|
|
13
|
+
require 'pry-byebug'
|
|
14
|
+
|
|
15
|
+
profile do
|
|
16
|
+
1_000_000.times do
|
|
17
|
+
Integers.new(integers)
|
|
18
|
+
end
|
|
19
|
+
end
|
data/benchmarks/setup.rb
ADDED
data/dry-struct.gemspec
CHANGED
|
@@ -27,10 +27,10 @@ Gem::Specification.new do |spec|
|
|
|
27
27
|
spec.bindir = 'exe'
|
|
28
28
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
29
29
|
spec.require_paths = ['lib']
|
|
30
|
-
spec.required_ruby_version = ">= 2.
|
|
30
|
+
spec.required_ruby_version = ">= 2.4.0"
|
|
31
31
|
|
|
32
32
|
spec.add_runtime_dependency 'dry-equalizer', '~> 0.2'
|
|
33
|
-
spec.add_runtime_dependency 'dry-types', '~> 0
|
|
33
|
+
spec.add_runtime_dependency 'dry-types', '~> 1.0'
|
|
34
34
|
spec.add_runtime_dependency 'dry-core', '~> 0.4', '>= 0.4.3'
|
|
35
35
|
spec.add_runtime_dependency 'ice_nine', '~> 0.11'
|
|
36
36
|
|
data/lib/dry/struct.rb
CHANGED
|
@@ -63,8 +63,8 @@ module Dry
|
|
|
63
63
|
# @example with a nested array of structs
|
|
64
64
|
# class Language < Dry::Struct
|
|
65
65
|
# attribute :name, Types::String
|
|
66
|
-
#
|
|
67
|
-
#
|
|
66
|
+
# attribute :versions, Types::Array.of(Types::String)
|
|
67
|
+
# attribute :celebrities, Types::Array.of(Dry::Struct) do
|
|
68
68
|
# attribute :name, Types::String
|
|
69
69
|
# attribute :pseudonym, Types::String
|
|
70
70
|
# end
|
|
@@ -157,8 +157,8 @@ module Dry
|
|
|
157
157
|
keys.each do |key|
|
|
158
158
|
next if instance_methods.include?(key)
|
|
159
159
|
class_eval(<<-RUBY)
|
|
160
|
-
def #{
|
|
161
|
-
@attributes[#{
|
|
160
|
+
def #{key}
|
|
161
|
+
@attributes[#{key.inspect}]
|
|
162
162
|
end
|
|
163
163
|
RUBY
|
|
164
164
|
end
|
|
@@ -222,16 +222,36 @@ module Dry
|
|
|
222
222
|
|
|
223
223
|
# @param [Hash{Symbol => Object},Dry::Struct] attributes
|
|
224
224
|
# @raise [Struct::Error] if the given attributes don't conform {#schema}
|
|
225
|
-
def new(attributes = default_attributes)
|
|
226
|
-
if attributes.
|
|
225
|
+
def new(attributes = default_attributes, safe = false)
|
|
226
|
+
if equal?(attributes.class)
|
|
227
227
|
attributes
|
|
228
|
+
elsif safe
|
|
229
|
+
load(schema.call_safe(attributes) { |output = attributes| return yield output })
|
|
228
230
|
else
|
|
229
|
-
|
|
231
|
+
load(schema.call_unsafe(attributes))
|
|
230
232
|
end
|
|
231
|
-
rescue Types::
|
|
233
|
+
rescue Types::CoercionError => error
|
|
232
234
|
raise Struct::Error, "[#{self}.new] #{error}"
|
|
233
235
|
end
|
|
234
236
|
|
|
237
|
+
# @api private
|
|
238
|
+
def call_safe(input, &block)
|
|
239
|
+
if input.is_a?(self)
|
|
240
|
+
input
|
|
241
|
+
else
|
|
242
|
+
new(input, true, &block)
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# @api private
|
|
247
|
+
def call_unsafe(input)
|
|
248
|
+
if input.is_a?(self)
|
|
249
|
+
input
|
|
250
|
+
else
|
|
251
|
+
new(input)
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
235
255
|
# @api private
|
|
236
256
|
def load(attributes)
|
|
237
257
|
struct = allocate
|
|
@@ -239,17 +259,6 @@ module Dry
|
|
|
239
259
|
struct
|
|
240
260
|
end
|
|
241
261
|
|
|
242
|
-
# Calls type constructor. The behavior is identical to `.new` but returns
|
|
243
|
-
# the input back if it's a subclass of the struct.
|
|
244
|
-
#
|
|
245
|
-
# @param [Hash{Symbol => Object},Dry::Struct] attributes
|
|
246
|
-
# @return [Dry::Struct]
|
|
247
|
-
def call(attributes = default_attributes)
|
|
248
|
-
return attributes if attributes.is_a?(self)
|
|
249
|
-
new(attributes)
|
|
250
|
-
end
|
|
251
|
-
alias_method :[], :call
|
|
252
|
-
|
|
253
262
|
# @param [#call,nil] constructor
|
|
254
263
|
# @param [Hash] _options
|
|
255
264
|
# @param [#call,nil] block
|
|
@@ -274,7 +283,7 @@ module Dry
|
|
|
274
283
|
# @private
|
|
275
284
|
def try_struct(input)
|
|
276
285
|
if input.is_a?(self)
|
|
277
|
-
|
|
286
|
+
input
|
|
278
287
|
else
|
|
279
288
|
yield
|
|
280
289
|
end
|
|
@@ -305,9 +314,10 @@ module Dry
|
|
|
305
314
|
|
|
306
315
|
# @param [Object, Dry::Struct] value
|
|
307
316
|
# @return [Boolean]
|
|
308
|
-
def
|
|
309
|
-
self
|
|
317
|
+
def ===(other)
|
|
318
|
+
other.is_a?(self)
|
|
310
319
|
end
|
|
320
|
+
alias_method :primitive?, :===
|
|
311
321
|
|
|
312
322
|
# @return [true]
|
|
313
323
|
def constrained?
|
|
@@ -324,6 +334,11 @@ module Dry
|
|
|
324
334
|
false
|
|
325
335
|
end
|
|
326
336
|
|
|
337
|
+
# @return [Proc]
|
|
338
|
+
def to_proc
|
|
339
|
+
proc { |input| call(input) }
|
|
340
|
+
end
|
|
341
|
+
|
|
327
342
|
# Checks if this {Struct} has the given attribute
|
|
328
343
|
#
|
|
329
344
|
# @param [Symbol] key Attribute name
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'dry/types/printer'
|
|
2
|
+
|
|
3
|
+
module Dry
|
|
4
|
+
module Types
|
|
5
|
+
# @api private
|
|
6
|
+
class Printer
|
|
7
|
+
MAPPING[Struct::Sum] = :visit_struct_sum
|
|
8
|
+
|
|
9
|
+
def visit_struct_sum(sum)
|
|
10
|
+
visit_sum_constructors(sum) do |constructors|
|
|
11
|
+
visit_options(EMPTY_HASH, sum.meta) do |opts|
|
|
12
|
+
yield "Struct::Sum<#{constructors}#{opts}>"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/dry/struct/sum.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'dry/types/sum'
|
|
2
|
+
require 'dry/types/printer'
|
|
2
3
|
|
|
3
4
|
module Dry
|
|
4
5
|
class Struct
|
|
@@ -6,6 +7,11 @@ module Dry
|
|
|
6
7
|
# As opposed to Dry::Types::Sum::Constrained
|
|
7
8
|
# this type tries no to coerce data first.
|
|
8
9
|
class Sum < Dry::Types::Sum::Constrained
|
|
10
|
+
def call(input)
|
|
11
|
+
left.try_struct(input) do
|
|
12
|
+
right.try_struct(input) { super }
|
|
13
|
+
end
|
|
14
|
+
end
|
|
9
15
|
# @param [Hash{Symbol => Object},Dry::Struct] input
|
|
10
16
|
# @yieldparam [Dry::Types::Result::Failure] failure
|
|
11
17
|
# @yieldreturn [Dry::Types::ResultResult]
|
|
@@ -23,12 +29,17 @@ module Dry
|
|
|
23
29
|
# @return [Dry::Types::Sum]
|
|
24
30
|
def |(type)
|
|
25
31
|
if type.is_a?(Class) && type <= Struct || type.is_a?(Sum)
|
|
26
|
-
|
|
32
|
+
Sum.new(self, type)
|
|
27
33
|
else
|
|
28
34
|
super
|
|
29
35
|
end
|
|
30
36
|
end
|
|
31
37
|
|
|
38
|
+
# @return [boolean]
|
|
39
|
+
def ===(value)
|
|
40
|
+
left === value || right === value
|
|
41
|
+
end
|
|
42
|
+
|
|
32
43
|
protected
|
|
33
44
|
|
|
34
45
|
# @private
|
data/lib/dry/struct/version.rb
CHANGED
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: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Piotr Solnica
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-
|
|
11
|
+
date: 2019-04-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: dry-equalizer
|
|
@@ -30,14 +30,14 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0
|
|
33
|
+
version: '1.0'
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0
|
|
40
|
+
version: '1.0'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: dry-core
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -147,6 +147,8 @@ files:
|
|
|
147
147
|
- Rakefile
|
|
148
148
|
- benchmarks/basic.rb
|
|
149
149
|
- benchmarks/constrained.rb
|
|
150
|
+
- benchmarks/profile_instantiation.rb
|
|
151
|
+
- benchmarks/setup.rb
|
|
150
152
|
- bin/console
|
|
151
153
|
- bin/setup
|
|
152
154
|
- dry-struct.gemspec
|
|
@@ -158,6 +160,7 @@ files:
|
|
|
158
160
|
- lib/dry/struct/extensions.rb
|
|
159
161
|
- lib/dry/struct/extensions/pretty_print.rb
|
|
160
162
|
- lib/dry/struct/hashify.rb
|
|
163
|
+
- lib/dry/struct/printer.rb
|
|
161
164
|
- lib/dry/struct/struct_builder.rb
|
|
162
165
|
- lib/dry/struct/sum.rb
|
|
163
166
|
- lib/dry/struct/value.rb
|
|
@@ -178,14 +181,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
178
181
|
requirements:
|
|
179
182
|
- - ">="
|
|
180
183
|
- !ruby/object:Gem::Version
|
|
181
|
-
version: 2.
|
|
184
|
+
version: 2.4.0
|
|
182
185
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
183
186
|
requirements:
|
|
184
187
|
- - ">="
|
|
185
188
|
- !ruby/object:Gem::Version
|
|
186
189
|
version: '0'
|
|
187
190
|
requirements: []
|
|
188
|
-
rubygems_version: 3.0.
|
|
191
|
+
rubygems_version: 3.0.3
|
|
189
192
|
signing_key:
|
|
190
193
|
specification_version: 4
|
|
191
194
|
summary: Typed structs and value objects.
|