dry-struct 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64b4b12493455f8f916b5708d7c2afdc2649099d3b7b8c41045b73517cce05f8
4
- data.tar.gz: 84989a15e01c83c1d71b0d5e034ca54d7727fc7c37db29c0e8b2db88ece51f15
3
+ metadata.gz: bf0892469a434b85578e7350f52039b85203dbd251ca5c4bd6b038373edc703e
4
+ data.tar.gz: 263e3d2d4ce824be64210a27d074fb42126dde12d94e56290307d9ff08c0efad
5
5
  SHA512:
6
- metadata.gz: 2462f24f972cbaa0c89399f76e3247c3b1fac9a6a88a0f1ea3a6e4ceb37fea2a463b58967c26b102456d589755fe2d3350c324b0646b870db27c6c434eba5acf
7
- data.tar.gz: 6156aa3704d9afffedc1370bf17371177d41696c289005fe5d41e4d356049ab881a6e40675756ab6bacd59ca4ac41f792a0dc872da9ffd2724b12cdd44c78e28
6
+ metadata.gz: '08ea5f7780bac10495f93a5043c5e100fc9386688920e4e7fd1b2304ceaeb8f37853f6ed70f5d5a69b1d7a30c0340450f8ce41fba91e812e00cf6a008f9c2de0'
7
+ data.tar.gz: da176db2c5d8127ea7ef6a088edf7f8f4d18c74e65d96e7f6a80dd9822c0baefdfa1dd7eb6d607ac077c033d64dcddb0ca6c1498eb411c4cd94ea96e23c701b4
@@ -1,9 +1,32 @@
1
+ <!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
2
+
3
+ ## 1.4.0 2021-01-21
4
+
5
+
6
+ ### Added
7
+
8
+ - Support for wrapping constructors and fallbacks, see release notes for dry-types 1.5.0 (@flash-gordon)
9
+ - Improvements of the attribute DSL, now it's possible to use optional structs as a base class (@flash-gordon)
10
+ ```ruby
11
+ class User < Dry::Struct
12
+ attribute :name, Types::String
13
+ attribute :address, Dry::Struct.optional do
14
+ attribute :city, Types::String
15
+ end
16
+ end
17
+
18
+ User.new(name: "John", address: nil) # => #<User name="John" address=nil>
19
+ ```
20
+
21
+
22
+ [Compare v1.3.0...v1.4.0](https://github.com/dry-rb/dry-struct/compare/v1.3.0...v1.4.0)
23
+
1
24
  ## 1.3.0 2020-02-10
2
25
 
3
26
 
4
27
  ### Added
5
28
 
6
- - Nested structures will reuse type and key transformations from of the enclosing struct (flash-gordon)
29
+ - Nested structures will reuse type and key transformations from the enclosing struct (@flash-gordon)
7
30
 
8
31
  ```ruby
9
32
  class User < Dry::Struct
@@ -22,13 +45,32 @@
22
45
  end
23
46
  end
24
47
  ```
25
- - `Dry::Struct::Constructor` finally acts like a fully-featured type (flash-gordon)
26
- - `Dry::Struct.abstract` declares a struct class as abstract. An abstract class is used as a default superclass for nested structs (flash-gordon)
27
- - `Struct.to_ast` and struct compiler (@flash-gordon)
48
+ - `Dry::Struct::Constructor` finally acts like a fully-featured type (@flash-gordon)
49
+ - `Dry::Struct.abstract` declares a struct class as abstract. An abstract class is used as a default superclass for nested structs (@flash-gordon)
50
+ - `Dry::Struct.to_ast` and struct compiler (@flash-gordon)
51
+ - Struct composition with `Dry::Struct.attributes_from`. It's more flexible than inheritance (@waiting-for-dev + @flash-gordon)
52
+
53
+ ```ruby
54
+ class Address < Dry::Struct
55
+ attribute :city, Types::String
56
+ attribute :zipcode, Types::String
57
+ end
58
+
59
+ class Buyer < Dry::Struct
60
+ attribute :name, Types::String
61
+ attributes_from Address
62
+ end
63
+
64
+ class Seller < Dry::Struct
65
+ attribute :name, Types::String
66
+ attribute :email, Types::String
67
+ attributes_from Address
68
+ end
69
+ ```
28
70
 
29
71
  ### Changed
30
72
 
31
- - [internal] metadata is now stored inside schema (flash-gordon)
73
+ - [internal] metadata is now stored inside schema (@flash-gordon)
32
74
 
33
75
  [Compare v1.2.0...v1.3.0](https://github.com/dry-rb/dry-struct/compare/v1.2.0...v1.3.0)
34
76
 
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015-2020 dry-rb team
3
+ Copyright (c) 2015-2021 dry-rb team
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
data/README.md CHANGED
@@ -21,7 +21,7 @@
21
21
 
22
22
  This library officially supports the following Ruby versions:
23
23
 
24
- * MRI >= `2.4`
24
+ * MRI >= `2.5`
25
25
  * jruby >= `9.2`
26
26
 
27
27
  ## License
@@ -25,12 +25,11 @@ Gem::Specification.new do |spec|
25
25
  spec.metadata['source_code_uri'] = 'https://github.com/dry-rb/dry-struct'
26
26
  spec.metadata['bug_tracker_uri'] = 'https://github.com/dry-rb/dry-struct/issues'
27
27
 
28
- spec.required_ruby_version = ">= 2.4.0"
28
+ spec.required_ruby_version = ">= 2.5.0"
29
29
 
30
30
  # to update dependencies edit project.yml
31
- spec.add_runtime_dependency "dry-core", "~> 0.4", ">= 0.4.4"
32
- spec.add_runtime_dependency "dry-equalizer", "~> 0.3"
33
- spec.add_runtime_dependency "dry-types", "~> 1.3"
31
+ spec.add_runtime_dependency "dry-core", "~> 0.5", ">= 0.5"
32
+ spec.add_runtime_dependency "dry-types", "~> 1.5"
34
33
  spec.add_runtime_dependency "ice_nine", "~> 0.11"
35
34
 
36
35
  spec.add_development_dependency "bundler"
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/struct'
3
+ require "dry/struct"
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry-types'
4
- require 'dry-equalizer'
5
- require 'dry/core/extensions'
6
- require 'dry/core/constants'
7
- require 'dry/core/deprecations'
8
-
9
- require 'dry/struct/version'
10
- require 'dry/struct/errors'
11
- require 'dry/struct/class_interface'
12
- require 'dry/struct/hashify'
13
- require 'dry/struct/struct_builder'
3
+ require "dry/types"
4
+ require "dry/core/equalizer"
5
+ require "dry/core/extensions"
6
+ require "dry/core/constants"
7
+ require "dry/core/deprecations"
8
+
9
+ require "dry/struct/version"
10
+ require "dry/struct/errors"
11
+ require "dry/struct/class_interface"
12
+ require "dry/struct/hashify"
13
+ require "dry/struct/struct_builder"
14
14
 
15
15
  module Dry
16
16
  # Constructor method for easily creating a {Dry::Struct}.
@@ -95,14 +95,14 @@ module Dry
95
95
  define_method(:prepend, ::Module.method(:prepend))
96
96
  end
97
97
 
98
- autoload :Value, 'dry/struct/value'
98
+ autoload :Value, "dry/struct/value"
99
99
 
100
100
  include ::Dry::Equalizer(:__attributes__, inspect: false, immutable: true)
101
101
 
102
102
  # {Dry::Types::Hash::Schema} subclass with specific behaviour defined for
103
103
  # @return [Dry::Types::Hash::Schema]
104
104
  defines :schema
105
- schema Types['coercible.hash'].schema(EMPTY_HASH)
105
+ schema Types["coercible.hash"].schema(EMPTY_HASH)
106
106
 
107
107
  defines :abstract_class
108
108
  abstract
@@ -134,7 +134,7 @@ module Dry
134
134
  # rom_n_roda[:title] #=> 'Web Development with ROM and Roda'
135
135
  # rom_n_roda[:subtitle] #=> nil
136
136
  def [](name)
137
- @attributes.fetch(name) { raise MissingAttributeError.new(name) }
137
+ @attributes.fetch(name) { raise MissingAttributeError, name }
138
138
  end
139
139
 
140
140
  # Converts the {Dry::Struct} to a hash with keys representing
@@ -185,8 +185,8 @@ module Dry
185
185
  def new(changeset)
186
186
  new_attributes = self.class.schema.apply(changeset, skip_missing: true, resolve_defaults: false)
187
187
  self.class.load(__attributes__.merge(new_attributes))
188
- rescue Types::SchemaError, Types::MissingKeyError, Types::UnknownKeysError => error
189
- raise Error, "[#{self}.new] #{error}"
188
+ rescue Types::SchemaError, Types::MissingKeyError, Types::UnknownKeysError => e
189
+ raise Error, "[#{self}.new] #{e}"
190
190
  end
191
191
  alias_method :__new__, :new
192
192
 
@@ -197,16 +197,16 @@ module Dry
197
197
  "#<#{klass.name || klass.inspect}#{attrs}>"
198
198
  end
199
199
 
200
- if RUBY_VERSION >= '2.7'
200
+ if RUBY_VERSION >= "2.7"
201
201
  # Pattern matching support
202
202
  #
203
203
  # @api private
204
- def deconstruct_keys(keys)
204
+ def deconstruct_keys(_keys)
205
205
  attributes
206
206
  end
207
207
  end
208
208
  end
209
209
  end
210
210
 
211
- require 'dry/struct/extensions'
212
- require 'dry/struct/printer'
211
+ require "dry/struct/extensions"
212
+ require "dry/struct/printer"
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'weakref'
4
- require 'dry/core/class_attributes'
5
- require 'dry/core/inflector'
6
- require 'dry/core/descendants_tracker'
3
+ require "weakref"
4
+ require "dry/core/class_attributes"
5
+ require "dry/core/inflector"
6
+ require "dry/core/descendants_tracker"
7
7
 
8
- require 'dry/struct/errors'
9
- require 'dry/struct/constructor'
10
- require 'dry/struct/sum'
8
+ require "dry/struct/errors"
9
+ require "dry/struct/constructor"
10
+ require "dry/struct/sum"
11
11
 
12
12
  module Dry
13
13
  class Struct
@@ -22,7 +22,7 @@ module Dry
22
22
  def inherited(klass)
23
23
  super
24
24
 
25
- unless klass.name.eql?('Dry::Struct::Value')
25
+ unless klass.name.eql?("Dry::Struct::Value")
26
26
  klass.extend(Core::DescendantsTracker)
27
27
  end
28
28
  end
@@ -149,8 +149,8 @@ module Dry
149
149
  def attribute?(*args, &block)
150
150
  if args.size == 1 && block.nil?
151
151
  Core::Deprecations.warn(
152
- 'Dry::Struct.attribute? is deprecated for checking attribute presence, '\
153
- 'use has_attribute? instead',
152
+ "Dry::Struct.attribute? is deprecated for checking attribute presence, "\
153
+ "use has_attribute? instead",
154
154
  tag: :'dry-struct'
155
155
  )
156
156
 
@@ -181,7 +181,7 @@ module Dry
181
181
  # # author: Constrained<Nominal<String> rule=[type?(String)]>
182
182
  # # }> fn=Kernel.Hash>]>
183
183
  def attributes(new_schema)
184
- keys = new_schema.keys.map { |k| k.to_s.chomp('?').to_sym }
184
+ keys = new_schema.keys.map { |k| k.to_s.chomp("?").to_sym }
185
185
  check_schema_duplication(keys)
186
186
 
187
187
  schema schema.schema(new_schema)
@@ -192,7 +192,7 @@ module Dry
192
192
 
193
193
  direct_descendants = descendants.select { |d| d.superclass == self }
194
194
  direct_descendants.each do |d|
195
- inherited_attrs = new_schema.reject { |k, _| d.has_attribute?(k.to_s.chomp('?').to_sym) }
195
+ inherited_attrs = new_schema.reject { |k, _| d.has_attribute?(k.to_s.chomp("?").to_sym) }
196
196
  d.attributes(inherited_attrs)
197
197
  end
198
198
 
@@ -233,7 +233,7 @@ module Dry
233
233
  schema schema.with_key_transform(proc || block)
234
234
  end
235
235
 
236
- # @param [Hash{Symbol => Dry::Types::Type, Dry::Struct}] new_schema
236
+ # @param [Hash{Symbol => Dry::Types::Type, Dry::Struct}] new_keys
237
237
  # @raise [RepeatedAttributeError] when trying to define attribute with the
238
238
  # same name as previously defined one
239
239
  def check_schema_duplication(new_keys)
@@ -264,8 +264,8 @@ module Dry
264
264
  else
265
265
  load(schema.call_unsafe(attributes))
266
266
  end
267
- rescue Types::CoercionError => error
268
- raise Error, "[#{self}.new] #{error}", error.backtrace
267
+ rescue Types::CoercionError => e
268
+ raise Error, "[#{self}.new] #{e}", e.backtrace
269
269
  end
270
270
 
271
271
  # @api private
@@ -289,7 +289,7 @@ module Dry
289
289
  # @api private
290
290
  def load(attributes)
291
291
  struct = allocate
292
- struct.send(:initialize, attributes)
292
+ struct.__send__(:initialize, attributes)
293
293
  struct
294
294
  end
295
295
 
@@ -297,7 +297,7 @@ module Dry
297
297
  # @param [#call,nil] block
298
298
  # @return [Dry::Struct::Constructor]
299
299
  def constructor(constructor = nil, **, &block)
300
- Constructor.new(self, fn: constructor || block)
300
+ Constructor[self, fn: constructor || block]
301
301
  end
302
302
 
303
303
  # @param [Hash{Symbol => Object},Dry::Struct] input
@@ -345,7 +345,7 @@ module Dry
345
345
  false
346
346
  end
347
347
 
348
- # @param [Object, Dry::Struct] value
348
+ # @param [Object, Dry::Struct] other
349
349
  # @return [Boolean]
350
350
  def ===(other)
351
351
  other.is_a?(self)
@@ -463,7 +463,7 @@ module Dry
463
463
  elsif block.nil? && Undefined.equal?(type)
464
464
  raise(
465
465
  ::ArgumentError,
466
- 'you must supply a type or a block to `Dry::Struct.attribute`'
466
+ "you must supply a type or a block to `Dry::Struct.attribute`"
467
467
  )
468
468
  else
469
469
  type
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'weakref'
4
- require 'dry/types/compiler'
3
+ require "weakref"
4
+ require "dry/types/compiler"
5
5
 
6
6
  module Dry
7
7
  class Struct
@@ -25,7 +25,7 @@ module Dry
25
25
  # This shouldn't happen in a working application
26
26
  class RecycledStructError < ::RuntimeError
27
27
  def initialize
28
- super('Reference to struct class was garbage collected')
28
+ super("Reference to struct class was garbage collected")
29
29
  end
30
30
  end
31
31
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Dry::Struct.register_extension(:pretty_print) do
4
- require 'dry/struct/extensions/pretty_print'
4
+ require "dry/struct/extensions/pretty_print"
5
5
  end
@@ -1,18 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pp'
3
+ require "pp"
4
4
 
5
5
  module Dry
6
6
  class Struct
7
7
  def pretty_print(pp)
8
8
  klass = self.class
9
- pp.group(1, "#<#{klass.name || klass.inspect}", '>') do
10
- pp.seplist(@attributes.keys, proc { pp.text ',' }) do |column_name|
9
+ pp.group(1, "#<#{klass.name || klass.inspect}", ">") do
10
+ pp.seplist(@attributes.keys, proc { pp.text "," }) do |column_name|
11
11
  column_value = @attributes[column_name]
12
- pp.breakable ' '
12
+ pp.breakable " "
13
13
  pp.group(1) do
14
14
  pp.text column_name
15
- pp.text '='
15
+ pp.text "="
16
16
  pp.pp column_value
17
17
  end
18
18
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/types/printer'
3
+ require "dry/types/printer"
4
4
 
5
5
  module Dry
6
6
  module Types
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/struct/compiler'
3
+ require "dry/struct/compiler"
4
4
 
5
5
  module Dry
6
6
  class Struct
@@ -30,10 +30,13 @@ module Dry
30
30
 
31
31
  class_exec(&block)
32
32
  end
33
+
33
34
  struct.const_set(const_name, new_type)
34
35
 
35
36
  if array?(type)
36
37
  type.of(new_type)
38
+ elsif optional?(type)
39
+ new_type.optional
37
40
  else
38
41
  new_type
39
42
  end
@@ -41,13 +44,23 @@ module Dry
41
44
 
42
45
  private
43
46
 
47
+ def type?(type)
48
+ type.is_a?(Types::Type)
49
+ end
50
+
44
51
  def array?(type)
45
- type.is_a?(Types::Type) && type.primitive.equal?(::Array)
52
+ type?(type) && !type.optional? && type.primitive.equal?(::Array)
53
+ end
54
+
55
+ def optional?(type)
56
+ type?(type) && type.optional?
46
57
  end
47
58
 
48
59
  def parent(type)
49
60
  if array?(type)
50
61
  visit(type.to_ast)
62
+ elsif optional?(type)
63
+ type.right
51
64
  else
52
65
  type
53
66
  end
@@ -65,10 +78,12 @@ module Dry
65
78
  end
66
79
 
67
80
  def check_name(name)
68
- raise(
69
- Error,
70
- "Can't create nested attribute - `#{struct}::#{name}` already defined"
71
- ) if struct.const_defined?(name, false)
81
+ if struct.const_defined?(name, false)
82
+ raise(
83
+ Error,
84
+ "Can't create nested attribute - `#{struct}::#{name}` already defined"
85
+ )
86
+ end
72
87
  end
73
88
 
74
89
  def visit_constrained(node)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/types/sum'
4
- require 'dry/types/printer'
3
+ require "dry/types/sum"
4
+ require "dry/types/printer"
5
5
 
6
6
  module Dry
7
7
  class Struct
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ice_nine'
4
- require 'dry/core/deprecations'
3
+ require "ice_nine"
4
+ require "dry/core/deprecations"
5
5
 
6
6
  module Dry
7
7
  class Struct
@@ -3,6 +3,6 @@
3
3
  module Dry
4
4
  class Struct
5
5
  # @private
6
- VERSION = '1.3.0'.freeze
6
+ VERSION = "1.4.0"
7
7
  end
8
8
  end
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.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-10 00:00:00.000000000 Z
11
+ date: 2021-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-core
@@ -16,48 +16,34 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.4'
19
+ version: '0.5'
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 0.4.4
22
+ version: '0.5'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: '0.4'
29
+ version: '0.5'
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 0.4.4
33
- - !ruby/object:Gem::Dependency
34
- name: dry-equalizer
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: '0.3'
40
- type: :runtime
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: '0.3'
32
+ version: '0.5'
47
33
  - !ruby/object:Gem::Dependency
48
34
  name: dry-types
49
35
  requirement: !ruby/object:Gem::Requirement
50
36
  requirements:
51
37
  - - "~>"
52
38
  - !ruby/object:Gem::Version
53
- version: '1.3'
39
+ version: '1.5'
54
40
  type: :runtime
55
41
  prerelease: false
56
42
  version_requirements: !ruby/object:Gem::Requirement
57
43
  requirements:
58
44
  - - "~>"
59
45
  - !ruby/object:Gem::Version
60
- version: '1.3'
46
+ version: '1.5'
61
47
  - !ruby/object:Gem::Dependency
62
48
  name: ice_nine
63
49
  requirement: !ruby/object:Gem::Requirement
@@ -169,14 +155,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
169
155
  requirements:
170
156
  - - ">="
171
157
  - !ruby/object:Gem::Version
172
- version: 2.4.0
158
+ version: 2.5.0
173
159
  required_rubygems_version: !ruby/object:Gem::Requirement
174
160
  requirements:
175
161
  - - ">="
176
162
  - !ruby/object:Gem::Version
177
163
  version: '0'
178
164
  requirements: []
179
- rubygems_version: 3.0.3
165
+ rubygems_version: 3.1.4
180
166
  signing_key:
181
167
  specification_version: 4
182
168
  summary: Typed structs and value objects