dry-struct 1.3.0 → 1.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.
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