dry-struct 1.3.0 → 1.6.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: f3309e15a4b8084a8ddb210a4d62e51e063a54f0aec56f41398f41824bbfe687
4
+ data.tar.gz: 05de1a1085a1753cd22f6f42a459de2245a544fe6ab822dff2bae228fe91da45
5
5
  SHA512:
6
- metadata.gz: 2462f24f972cbaa0c89399f76e3247c3b1fac9a6a88a0f1ea3a6e4ceb37fea2a463b58967c26b102456d589755fe2d3350c324b0646b870db27c6c434eba5acf
7
- data.tar.gz: 6156aa3704d9afffedc1370bf17371177d41696c289005fe5d41e4d356049ab881a6e40675756ab6bacd59ca4ac41f792a0dc872da9ffd2724b12cdd44c78e28
6
+ metadata.gz: 16f8476d1362fa11871db6be02787e8b106795ca5d4a1ebeb1c796cc22abcd5ee0c0cf8f7985191a180dcfb38a1679535be4ff13003e0b08459072a2b236e288
7
+ data.tar.gz: e8973dbc9cc1fc0033751299ac366504c047cd996e9e9c5718ecad6e2d4bf2cdb734d46fd76f99c074a7982cb8cff6f9085a18725a01b21ea6e42475218f06e5
data/CHANGELOG.md CHANGED
@@ -1,9 +1,70 @@
1
+ <!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
2
+
3
+ ## 1.6.0 2022-11-04
4
+
5
+
6
+ ### Changed
7
+
8
+ - This version uses dry-core 1.0 (@flash-gordon + @solnic)
9
+
10
+ [Compare v1.5.2...v1.6.0](https://github.com/dry-rb/dry-struct/compare/v1.5.2...v1.6.0)
11
+
12
+ ## 1.5.2 2022-10-19
13
+
14
+
15
+ ### Fixed
16
+
17
+ - Coercion failures keep the original error instead of just having a string (@flash-gordon + @newx)
18
+
19
+
20
+ [Compare v1.5.1...v1.5.2](https://github.com/dry-rb/dry-struct/compare/v1.5.1...v1.5.2)
21
+
22
+ ## 1.5.1 2022-10-17
23
+
24
+
25
+ ### Fixed
26
+
27
+ - Fixed issues with auto-loading `Extensions` module (issue #183 fixed via #184) (@solnic)
28
+
29
+
30
+ [Compare v1.5.0...v1.5.1](https://github.com/dry-rb/dry-struct/compare/v1.5.0...v1.5.1)
31
+
32
+ ## 1.5.0 2022-10-15
33
+
34
+
35
+ ### Changed
36
+
37
+ - Use zeitwerk for auto-loading (@flash-gordon)
38
+
39
+ [Compare v1.4.0...v1.5.0](https://github.com/dry-rb/dry-struct/compare/v1.4.0...v1.5.0)
40
+
41
+ ## 1.4.0 2021-01-21
42
+
43
+
44
+ ### Added
45
+
46
+ - Support for wrapping constructors and fallbacks, see release notes for dry-types 1.5.0 (@flash-gordon)
47
+ - Improvements of the attribute DSL, now it's possible to use optional structs as a base class (@flash-gordon)
48
+ ```ruby
49
+ class User < Dry::Struct
50
+ attribute :name, Types::String
51
+ attribute :address, Dry::Struct.optional do
52
+ attribute :city, Types::String
53
+ end
54
+ end
55
+
56
+ User.new(name: "John", address: nil) # => #<User name="John" address=nil>
57
+ ```
58
+
59
+
60
+ [Compare v1.3.0...v1.4.0](https://github.com/dry-rb/dry-struct/compare/v1.3.0...v1.4.0)
61
+
1
62
  ## 1.3.0 2020-02-10
2
63
 
3
64
 
4
65
  ### Added
5
66
 
6
- - Nested structures will reuse type and key transformations from of the enclosing struct (flash-gordon)
67
+ - Nested structures will reuse type and key transformations from the enclosing struct (@flash-gordon)
7
68
 
8
69
  ```ruby
9
70
  class User < Dry::Struct
@@ -22,13 +83,32 @@
22
83
  end
23
84
  end
24
85
  ```
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)
86
+ - `Dry::Struct::Constructor` finally acts like a fully-featured type (@flash-gordon)
87
+ - `Dry::Struct.abstract` declares a struct class as abstract. An abstract class is used as a default superclass for nested structs (@flash-gordon)
88
+ - `Dry::Struct.to_ast` and struct compiler (@flash-gordon)
89
+ - Struct composition with `Dry::Struct.attributes_from`. It's more flexible than inheritance (@waiting-for-dev + @flash-gordon)
90
+
91
+ ```ruby
92
+ class Address < Dry::Struct
93
+ attribute :city, Types::String
94
+ attribute :zipcode, Types::String
95
+ end
96
+
97
+ class Buyer < Dry::Struct
98
+ attribute :name, Types::String
99
+ attributes_from Address
100
+ end
101
+
102
+ class Seller < Dry::Struct
103
+ attribute :name, Types::String
104
+ attribute :email, Types::String
105
+ attributes_from Address
106
+ end
107
+ ```
28
108
 
29
109
  ### Changed
30
110
 
31
- - [internal] metadata is now stored inside schema (flash-gordon)
111
+ - [internal] metadata is now stored inside schema (@flash-gordon)
32
112
 
33
113
  [Compare v1.2.0...v1.3.0](https://github.com/dry-rb/dry-struct/compare/v1.2.0...v1.3.0)
34
114
 
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-2022 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
@@ -1,3 +1,4 @@
1
+ <!--- this file is synced from dry-rb/template-gem project -->
1
2
  [gem]: https://rubygems.org/gems/dry-struct
2
3
  [actions]: https://github.com/dry-rb/dry-struct/actions
3
4
  [codacy]: https://www.codacy.com/gh/dry-rb/dry-struct
@@ -10,19 +11,19 @@
10
11
  [![CI Status](https://github.com/dry-rb/dry-struct/workflows/ci/badge.svg)][actions]
11
12
  [![Codacy Badge](https://api.codacy.com/project/badge/Grade/961f5c776f1d49218b2cede3745e059c)][codacy]
12
13
  [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/961f5c776f1d49218b2cede3745e059c)][codacy]
13
- [![Inline docs](http://inch-ci.org/github/dry-rb/dry-struct.svg?branch=master)][inchpages]
14
+ [![Inline docs](http://inch-ci.org/github/dry-rb/dry-struct.svg?branch=main)][inchpages]
14
15
 
15
16
  ## Links
16
17
 
17
- * [User documentation](http://dry-rb.org/gems/dry-struct)
18
+ * [User documentation](https://dry-rb.org/gems/dry-struct)
18
19
  * [API documentation](http://rubydoc.info/gems/dry-struct)
19
20
 
20
21
  ## Supported Ruby versions
21
22
 
22
23
  This library officially supports the following Ruby versions:
23
24
 
24
- * MRI >= `2.4`
25
- * jruby >= `9.2`
25
+ * MRI `>= 2.7.0`
26
+ * jruby `>= 9.3` (postponed until 2.7 is supported)
26
27
 
27
28
  ## License
28
29
 
data/dry-struct.gemspec CHANGED
@@ -1,37 +1,38 @@
1
1
  # frozen_string_literal: true
2
- # this file is managed by dry-rb/devtools project
3
2
 
4
- lib = File.expand_path('lib', __dir__)
3
+ # this file is synced from dry-rb/template-gem project
4
+
5
+ lib = File.expand_path("lib", __dir__)
5
6
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
- require 'dry/struct/version'
7
+ require "dry/struct/version"
7
8
 
8
9
  Gem::Specification.new do |spec|
9
- spec.name = 'dry-struct'
10
+ spec.name = "dry-struct"
10
11
  spec.authors = ["Piotr Solnica"]
11
12
  spec.email = ["piotr.solnica@gmail.com"]
12
- spec.license = 'MIT'
13
+ spec.license = "MIT"
13
14
  spec.version = Dry::Struct::VERSION.dup
14
15
 
15
16
  spec.summary = "Typed structs and value objects"
16
17
  spec.description = spec.summary
17
- spec.homepage = 'https://dry-rb.org/gems/dry-struct'
18
+ spec.homepage = "https://dry-rb.org/gems/dry-struct"
18
19
  spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-struct.gemspec", "lib/**/*"]
19
- spec.bindir = 'bin'
20
+ spec.bindir = "bin"
20
21
  spec.executables = []
21
- spec.require_paths = ['lib']
22
+ spec.require_paths = ["lib"]
22
23
 
23
- spec.metadata['allowed_push_host'] = 'https://rubygems.org'
24
- spec.metadata['changelog_uri'] = 'https://github.com/dry-rb/dry-struct/blob/master/CHANGELOG.md'
25
- spec.metadata['source_code_uri'] = 'https://github.com/dry-rb/dry-struct'
26
- spec.metadata['bug_tracker_uri'] = 'https://github.com/dry-rb/dry-struct/issues'
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"
27
28
 
28
- spec.required_ruby_version = ">= 2.4.0"
29
+ spec.required_ruby_version = ">= 2.7.0"
29
30
 
30
31
  # 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"
32
+ spec.add_runtime_dependency "dry-core", "~> 1.0", "< 2"
33
+ spec.add_runtime_dependency "dry-types", ">= 1.7", "< 2"
34
34
  spec.add_runtime_dependency "ice_nine", "~> 0.11"
35
+ spec.add_runtime_dependency "zeitwerk", "~> 2.6"
35
36
 
36
37
  spec.add_development_dependency "bundler"
37
38
  spec.add_development_dependency "rake"
@@ -1,18 +1,11 @@
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'
7
-
8
- require 'dry/struct/errors'
9
- require 'dry/struct/constructor'
10
- require 'dry/struct/sum'
3
+ require "weakref"
11
4
 
12
5
  module Dry
13
6
  class Struct
14
7
  # Class-level interface of {Struct} and {Value}
15
- module ClassInterface
8
+ module ClassInterface # rubocop:disable Metrics/ModuleLength
16
9
  include Core::ClassAttributes
17
10
 
18
11
  include Types::Type
@@ -22,7 +15,7 @@ module Dry
22
15
  def inherited(klass)
23
16
  super
24
17
 
25
- unless klass.name.eql?('Dry::Struct::Value')
18
+ unless klass.name.eql?("Dry::Struct::Value")
26
19
  klass.extend(Core::DescendantsTracker)
27
20
  end
28
21
  end
@@ -49,8 +42,12 @@ module Dry
49
42
  # end
50
43
  # end
51
44
  #
52
- # Language.schema
53
- # # => #<Dry::Types[Constructor<Schema<keys={name: Constrained<Nominal<String> rule=[type?(String)]> details: Language::Details}> fn=Kernel.Hash>]>
45
+ # Language.schema # new lines for readability
46
+ # # => #<Dry::Types[
47
+ # Constructor<Schema<keys={
48
+ # name: Constrained<Nominal<String> rule=[type?(String)]>
49
+ # details: Language::Details
50
+ # }> fn=Kernel.Hash>]>
54
51
  #
55
52
  # ruby = Language.new(name: 'Ruby', details: { type: 'OO' })
56
53
  # ruby.name #=> 'Ruby'
@@ -67,10 +64,12 @@ module Dry
67
64
  # end
68
65
  # end
69
66
  #
70
- # Language.schema
67
+ # Language.schema # new lines for readability
71
68
  # => #<Dry::Types[Constructor<Schema<keys={
72
69
  # name: Constrained<Nominal<String> rule=[type?(String)]>
73
- # versions: Constrained<Array<Constrained<Nominal<String> rule=[type?(String)]>> rule=[type?(Array)]>
70
+ # versions: Constrained<
71
+ # Array<Constrained<Nominal<String> rule=[type?(String)]>
72
+ # > rule=[type?(Array)]>
74
73
  # celebrities: Constrained<Array<Language::Celebrity> rule=[type?(Array)]>
75
74
  # }> fn=Kernel.Hash>]>
76
75
  #
@@ -149,9 +148,9 @@ module Dry
149
148
  def attribute?(*args, &block)
150
149
  if args.size == 1 && block.nil?
151
150
  Core::Deprecations.warn(
152
- 'Dry::Struct.attribute? is deprecated for checking attribute presence, '\
153
- 'use has_attribute? instead',
154
- tag: :'dry-struct'
151
+ "Dry::Struct.attribute? is deprecated for checking attribute presence, "\
152
+ "use has_attribute? instead",
153
+ tag: :"dry-struct"
155
154
  )
156
155
 
157
156
  has_attribute?(args[0])
@@ -181,7 +180,7 @@ module Dry
181
180
  # # author: Constrained<Nominal<String> rule=[type?(String)]>
182
181
  # # }> fn=Kernel.Hash>]>
183
182
  def attributes(new_schema)
184
- keys = new_schema.keys.map { |k| k.to_s.chomp('?').to_sym }
183
+ keys = new_schema.keys.map { |k| k.to_s.chomp("?").to_sym }
185
184
  check_schema_duplication(keys)
186
185
 
187
186
  schema schema.schema(new_schema)
@@ -192,7 +191,7 @@ module Dry
192
191
 
193
192
  direct_descendants = descendants.select { |d| d.superclass == self }
194
193
  direct_descendants.each do |d|
195
- inherited_attrs = new_schema.reject { |k, _| d.has_attribute?(k.to_s.chomp('?').to_sym) }
194
+ inherited_attrs = new_schema.reject { |k, _| d.has_attribute?(k.to_s.chomp("?").to_sym) }
196
195
  d.attributes(inherited_attrs)
197
196
  end
198
197
 
@@ -233,7 +232,7 @@ module Dry
233
232
  schema schema.with_key_transform(proc || block)
234
233
  end
235
234
 
236
- # @param [Hash{Symbol => Dry::Types::Type, Dry::Struct}] new_schema
235
+ # @param [Hash{Symbol => Dry::Types::Type, Dry::Struct}] new_keys
237
236
  # @raise [RepeatedAttributeError] when trying to define attribute with the
238
237
  # same name as previously defined one
239
238
  def check_schema_duplication(new_keys)
@@ -247,7 +246,7 @@ module Dry
247
246
 
248
247
  # @param [Hash{Symbol => Object},Dry::Struct] attributes
249
248
  # @raise [Struct::Error] if the given attributes don't conform {#schema}
250
- def new(attributes = default_attributes, safe = false, &block)
249
+ def new(attributes = default_attributes, safe = false, &block) # rubocop:disable Style/OptionalBooleanParameter
251
250
  if attributes.is_a?(Struct)
252
251
  if equal?(attributes.class)
253
252
  attributes
@@ -264,8 +263,8 @@ module Dry
264
263
  else
265
264
  load(schema.call_unsafe(attributes))
266
265
  end
267
- rescue Types::CoercionError => error
268
- raise Error, "[#{self}.new] #{error}", error.backtrace
266
+ rescue Types::CoercionError => e
267
+ raise Error, "[#{self}.new] #{e}", e.backtrace
269
268
  end
270
269
 
271
270
  # @api private
@@ -289,7 +288,7 @@ module Dry
289
288
  # @api private
290
289
  def load(attributes)
291
290
  struct = allocate
292
- struct.send(:initialize, attributes)
291
+ struct.__send__(:initialize, attributes)
293
292
  struct
294
293
  end
295
294
 
@@ -297,17 +296,17 @@ module Dry
297
296
  # @param [#call,nil] block
298
297
  # @return [Dry::Struct::Constructor]
299
298
  def constructor(constructor = nil, **, &block)
300
- Constructor.new(self, fn: constructor || block)
299
+ Constructor[self, fn: constructor || block]
301
300
  end
302
301
 
303
302
  # @param [Hash{Symbol => Object},Dry::Struct] input
304
303
  # @yieldparam [Dry::Types::Result::Failure] failure
305
- # @yieldreturn [Dry::Types::ResultResult]
304
+ # @yieldreturn [Dry::Types::Result]
306
305
  # @return [Dry::Types::Result]
307
306
  def try(input)
308
307
  success(self[input])
309
308
  rescue Error => e
310
- failure_result = failure(input, e.message)
309
+ failure_result = failure(input, e)
311
310
  block_given? ? yield(failure_result) : failure_result
312
311
  end
313
312
 
@@ -345,7 +344,7 @@ module Dry
345
344
  false
346
345
  end
347
346
 
348
- # @param [Object, Dry::Struct] value
347
+ # @param [Object, Dry::Struct] other
349
348
  # @return [Boolean]
350
349
  def ===(other)
351
350
  other.is_a?(self)
@@ -463,7 +462,7 @@ module Dry
463
462
  elsif block.nil? && Undefined.equal?(type)
464
463
  raise(
465
464
  ::ArgumentError,
466
- 'you must supply a type or a block to `Dry::Struct.attribute`'
465
+ "you must supply a type or a block to `Dry::Struct.attribute`"
467
466
  )
468
467
  else
469
468
  type
@@ -481,10 +480,10 @@ module Dry
481
480
  keys.each do |key|
482
481
  next if instance_methods.include?(key)
483
482
 
484
- class_eval(<<-RUBY)
485
- def #{key}
486
- @attributes[#{key.inspect}]
487
- end
483
+ class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
484
+ def #{key} # def email
485
+ @attributes[#{key.inspect}] # @attributes[:email]
486
+ end # end
488
487
  RUBY
489
488
  end
490
489
  end
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'weakref'
4
- require 'dry/types/compiler'
5
-
6
3
  module Dry
7
4
  class Struct
8
5
  class Compiler < Types::Compiler
@@ -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,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
- pp.text column_name
15
- pp.text '='
14
+ pp.text column_name.to_s
15
+ pp.text "="
16
16
  pp.pp column_value
17
17
  end
18
18
  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,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,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/struct/compiler'
4
-
5
3
  module Dry
6
4
  class Struct
7
5
  # @private
@@ -14,7 +12,8 @@ module Dry
14
12
  end
15
13
 
16
14
  # @param [Symbol|String] attr_name the name of the nested type
17
- # @param [Dry::Struct,Dry::Types::Type::Array,Undefined] type the superclass of the nested struct
15
+ # @param [Dry::Struct,Dry::Types::Type::Array,Undefined] type the superclass
16
+ # of the nested struct
18
17
  # @yield the body of the nested struct
19
18
  def call(attr_name, type, &block)
20
19
  const_name = const_name(type, attr_name)
@@ -30,10 +29,13 @@ module Dry
30
29
 
31
30
  class_exec(&block)
32
31
  end
32
+
33
33
  struct.const_set(const_name, new_type)
34
34
 
35
35
  if array?(type)
36
36
  type.of(new_type)
37
+ elsif optional?(type)
38
+ new_type.optional
37
39
  else
38
40
  new_type
39
41
  end
@@ -41,13 +43,23 @@ module Dry
41
43
 
42
44
  private
43
45
 
46
+ def type?(type)
47
+ type.is_a?(Types::Type)
48
+ end
49
+
44
50
  def array?(type)
45
- type.is_a?(Types::Type) && type.primitive.equal?(::Array)
51
+ type?(type) && !type.optional? && type.primitive.equal?(::Array)
52
+ end
53
+
54
+ def optional?(type)
55
+ type?(type) && type.optional?
46
56
  end
47
57
 
48
58
  def parent(type)
49
59
  if array?(type)
50
60
  visit(type.to_ast)
61
+ elsif optional?(type)
62
+ type.right
51
63
  else
52
64
  type
53
65
  end
@@ -65,10 +77,12 @@ module Dry
65
77
  end
66
78
 
67
79
  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)
80
+ if struct.const_defined?(name, false)
81
+ raise(
82
+ Error,
83
+ "Can't create nested attribute - `#{struct}::#{name}` already defined"
84
+ )
85
+ end
72
86
  end
73
87
 
74
88
  def visit_constrained(node)
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/types/sum'
4
- require 'dry/types/printer'
5
-
6
3
  module Dry
7
4
  class Struct
8
5
  # A sum type of two or more structs
@@ -17,7 +14,7 @@ module Dry
17
14
 
18
15
  # @param [Hash{Symbol => Object},Dry::Struct] input
19
16
  # @yieldparam [Dry::Types::Result::Failure] failure
20
- # @yieldreturn [Dry::Types::ResultResult]
17
+ # @yieldreturn [Dry::Types::Result]
21
18
  # @return [Dry::Types::Result]
22
19
  def try(input)
23
20
  if input.is_a?(Struct)
@@ -46,9 +43,9 @@ module Dry
46
43
  protected
47
44
 
48
45
  # @private
49
- def try_struct(input)
46
+ def try_struct(input, &block)
50
47
  left.try_struct(input) do
51
- right.try_struct(input) { yield }
48
+ right.try_struct(input, &block)
52
49
  end
53
50
  end
54
51
  end
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ice_nine'
4
- require 'dry/core/deprecations'
3
+ require "ice_nine"
5
4
 
6
5
  module Dry
7
6
  class Struct
8
- extend Core::Deprecations[:'dry-struct']
7
+ extend Core::Deprecations[:"dry-struct"]
9
8
 
10
9
  # {Value} objects behave like {Struct}s but *deeply frozen*
11
10
  # using [`ice_nine`](https://github.com/dkubb/ice_nine)
@@ -3,6 +3,6 @@
3
3
  module Dry
4
4
  class Struct
5
5
  # @private
6
- VERSION = '1.3.0'.freeze
6
+ VERSION = "1.6.0"
7
7
  end
8
8
  end
data/lib/dry/struct.rb CHANGED
@@ -1,16 +1,13 @@
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 "weakref"
4
+
5
+ require "dry/core"
6
+ require "dry/types"
7
+
8
+ require "dry/struct/class_interface"
9
+ require "dry/struct/errors"
10
+ require "dry/struct/version"
14
11
 
15
12
  module Dry
16
13
  # Constructor method for easily creating a {Dry::Struct}.
@@ -88,21 +85,35 @@ module Dry
88
85
  extend Core::Extensions
89
86
  include Core::Constants
90
87
  extend ClassInterface
91
- extend Core::Deprecations[:'dry-struct']
88
+ extend Core::Deprecations[:"dry-struct"]
92
89
 
93
90
  class << self
94
91
  # override `Dry::Types::Builder#prepend`
95
92
  define_method(:prepend, ::Module.method(:prepend))
93
+
94
+ def loader
95
+ @loader ||= ::Zeitwerk::Loader.new.tap do |loader|
96
+ root = ::File.expand_path("..", __dir__)
97
+ loader.tag = "dry-struct"
98
+ loader.inflector = ::Zeitwerk::GemInflector.new("#{root}/dry-struct.rb")
99
+ loader.push_dir(root)
100
+ loader.ignore(
101
+ "#{root}/dry-struct.rb",
102
+ "#{root}/dry/struct/{class_interface,errors,extensions,printer,value,version}.rb",
103
+ "#{root}/dry/struct/extensions"
104
+ )
105
+ end
106
+ end
96
107
  end
97
108
 
98
- autoload :Value, 'dry/struct/value'
109
+ loader.setup
99
110
 
100
111
  include ::Dry::Equalizer(:__attributes__, inspect: false, immutable: true)
101
112
 
102
113
  # {Dry::Types::Hash::Schema} subclass with specific behaviour defined for
103
114
  # @return [Dry::Types::Hash::Schema]
104
115
  defines :schema
105
- schema Types['coercible.hash'].schema(EMPTY_HASH)
116
+ schema Types["coercible.hash"].schema(EMPTY_HASH)
106
117
 
107
118
  defines :abstract_class
108
119
  abstract
@@ -134,7 +145,7 @@ module Dry
134
145
  # rom_n_roda[:title] #=> 'Web Development with ROM and Roda'
135
146
  # rom_n_roda[:subtitle] #=> nil
136
147
  def [](name)
137
- @attributes.fetch(name) { raise MissingAttributeError.new(name) }
148
+ @attributes.fetch(name) { raise MissingAttributeError, name }
138
149
  end
139
150
 
140
151
  # Converts the {Dry::Struct} to a hash with keys representing
@@ -159,8 +170,8 @@ module Dry
159
170
  result[key.name] = Hashify[self[key.name]] if attributes.key?(key.name)
160
171
  end
161
172
  end
173
+ # TODO: remove in 2.0
162
174
  alias_method :to_hash, :to_h
163
- # deprecate :to_hash, :to_h, message: "Implicit convertion structs to hashes is deprecated. Use .to_h"
164
175
 
165
176
  # Create a copy of {Dry::Struct} with overriden attributes
166
177
  #
@@ -183,10 +194,14 @@ module Dry
183
194
  # rom_n_roda.new(subtitle: '3rd edition')
184
195
  # #=> #<Book title="Web Development with ROM and Roda" subtitle="3rd edition">
185
196
  def new(changeset)
186
- new_attributes = self.class.schema.apply(changeset, skip_missing: true, resolve_defaults: false)
197
+ new_attributes = self.class.schema.apply(
198
+ changeset,
199
+ skip_missing: true,
200
+ resolve_defaults: false
201
+ )
187
202
  self.class.load(__attributes__.merge(new_attributes))
188
- rescue Types::SchemaError, Types::MissingKeyError, Types::UnknownKeysError => error
189
- raise Error, "[#{self}.new] #{error}"
203
+ rescue Types::SchemaError, Types::MissingKeyError, Types::UnknownKeysError => e
204
+ raise Error, "[#{self}.new] #{e}"
190
205
  end
191
206
  alias_method :__new__, :new
192
207
 
@@ -197,16 +212,15 @@ module Dry
197
212
  "#<#{klass.name || klass.inspect}#{attrs}>"
198
213
  end
199
214
 
200
- if RUBY_VERSION >= '2.7'
201
- # Pattern matching support
202
- #
203
- # @api private
204
- def deconstruct_keys(keys)
205
- attributes
206
- end
215
+ # Pattern matching support
216
+ #
217
+ # @api private
218
+ def deconstruct_keys(_keys)
219
+ attributes
207
220
  end
208
221
  end
209
222
  end
210
223
 
211
- require 'dry/struct/extensions'
212
- require 'dry/struct/printer'
224
+ require "dry/struct/extensions"
225
+ require "dry/struct/printer"
226
+ require "dry/struct/value"
data/lib/dry-struct.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/struct'
3
+ require "dry/struct"
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.6.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: 2022-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-core
@@ -16,62 +16,68 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.4'
20
- - - ">="
19
+ version: '1.0'
20
+ - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: 0.4.4
22
+ version: '2'
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'
30
- - - ">="
29
+ version: '1.0'
30
+ - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: 0.4.4
32
+ version: '2'
33
33
  - !ruby/object:Gem::Dependency
34
- name: dry-equalizer
34
+ name: dry-types
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - "~>"
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '1.7'
40
+ - - "<"
38
41
  - !ruby/object:Gem::Version
39
- version: '0.3'
42
+ version: '2'
40
43
  type: :runtime
41
44
  prerelease: false
42
45
  version_requirements: !ruby/object:Gem::Requirement
43
46
  requirements:
44
- - - "~>"
47
+ - - ">="
45
48
  - !ruby/object:Gem::Version
46
- version: '0.3'
49
+ version: '1.7'
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '2'
47
53
  - !ruby/object:Gem::Dependency
48
- name: dry-types
54
+ name: ice_nine
49
55
  requirement: !ruby/object:Gem::Requirement
50
56
  requirements:
51
57
  - - "~>"
52
58
  - !ruby/object:Gem::Version
53
- version: '1.3'
59
+ version: '0.11'
54
60
  type: :runtime
55
61
  prerelease: false
56
62
  version_requirements: !ruby/object:Gem::Requirement
57
63
  requirements:
58
64
  - - "~>"
59
65
  - !ruby/object:Gem::Version
60
- version: '1.3'
66
+ version: '0.11'
61
67
  - !ruby/object:Gem::Dependency
62
- name: ice_nine
68
+ name: zeitwerk
63
69
  requirement: !ruby/object:Gem::Requirement
64
70
  requirements:
65
71
  - - "~>"
66
72
  - !ruby/object:Gem::Version
67
- version: '0.11'
73
+ version: '2.6'
68
74
  type: :runtime
69
75
  prerelease: false
70
76
  version_requirements: !ruby/object:Gem::Requirement
71
77
  requirements:
72
78
  - - "~>"
73
79
  - !ruby/object:Gem::Version
74
- version: '0.11'
80
+ version: '2.6'
75
81
  - !ruby/object:Gem::Dependency
76
82
  name: bundler
77
83
  requirement: !ruby/object:Gem::Requirement
@@ -158,7 +164,7 @@ licenses:
158
164
  - MIT
159
165
  metadata:
160
166
  allowed_push_host: https://rubygems.org
161
- changelog_uri: https://github.com/dry-rb/dry-struct/blob/master/CHANGELOG.md
167
+ changelog_uri: https://github.com/dry-rb/dry-struct/blob/main/CHANGELOG.md
162
168
  source_code_uri: https://github.com/dry-rb/dry-struct
163
169
  bug_tracker_uri: https://github.com/dry-rb/dry-struct/issues
164
170
  post_install_message:
@@ -169,14 +175,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
169
175
  requirements:
170
176
  - - ">="
171
177
  - !ruby/object:Gem::Version
172
- version: 2.4.0
178
+ version: 2.7.0
173
179
  required_rubygems_version: !ruby/object:Gem::Requirement
174
180
  requirements:
175
181
  - - ">="
176
182
  - !ruby/object:Gem::Version
177
183
  version: '0'
178
184
  requirements: []
179
- rubygems_version: 3.0.3
185
+ rubygems_version: 3.1.6
180
186
  signing_key:
181
187
  specification_version: 4
182
188
  summary: Typed structs and value objects