dry-struct 0.7.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Join the chat at https://
|
7
|
+
# dry-struct [![Join the chat at https://dry-rb.zulipchat.com](https://img.shields.io/badge/dry--rb-join%20chat-%23346b7a.svg)][chat]
|
8
8
|
|
9
9
|
[![Gem Version](https://badge.fury.io/rb/dry-struct.svg)][gem]
|
10
10
|
[![Build Status](https://travis-ci.org/dry-rb/dry-struct.svg?branch=master)][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.
|