dry-schema 1.10.1 → 1.10.4

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: 8aa8d227152a712ff8580d62686ad5a4b83b4439dc8d58f42651b869e203697c
4
- data.tar.gz: e22028010d0ac11567a8a615725496f77db8a2acd107350363b20174da01a20c
3
+ metadata.gz: 3a3fdab16834d270d9cdfd3788fffb0899b711fc946e6aa3f4bc98115983acb7
4
+ data.tar.gz: c8349be888a2d957ba67137a7877828031d385e1452793730654cee3a9994e68
5
5
  SHA512:
6
- metadata.gz: ad3350414c764971f4c0e69ca07044901d67488625c691f2a7396c6d17b33d31a2714e8959d5f07598c03894883b7854090c6d77b182f7569acc7a32b43be3d3
7
- data.tar.gz: 93320abcdadd4f3c48666507f829d4aaba2c9fc5ae181d2cd68f44e28eb850a8ead7adec29c7be935e17fe4112df09d17ac735dac9f50c49d45e5031f15d1ce6
6
+ metadata.gz: 23d0a177d1b2bfe8ba70ca0de182785ef9016d271e28ae36dd5590aae7f0b30d6a9ae1336948d3a862bf6b04afcc75cb2a115c3de589509cf46bd4a471c5e054
7
+ data.tar.gz: 478dc03869f1913f736db5ec2c69ff17c68440463f4cf23f337ef5d3b41cc944242075ce0bc36c1971765563566eb2d86e15f54ff7e1d762f6dbd6ccb3217947
data/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  <!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
2
2
 
3
+ ## 1.10.4 2022-10-13
4
+
5
+
6
+ ### Fixed
7
+
8
+ - Once again reverting zeitwerk related changes that were included in 1.10.3 by an accident :( (@solnic)
9
+
10
+
11
+ [Compare v1.10.3...v1.10.4](https://github.com/dry-rb/dry-schema/compare/v1.10.3...v1.10.4)
12
+
13
+ ## 1.10.3 2022-10-10
14
+
15
+
16
+ ### Fixed
17
+
18
+ - Addressed regressions causing issues with handling sum types (see #419 and #423 fixed via #425) (@robhanlon22)
19
+
20
+
21
+ [Compare v1.10.2...v1.10.3](https://github.com/dry-rb/dry-schema/compare/v1.10.2...v1.10.3)
22
+
23
+ ## 1.10.2 2022-08-23
24
+
25
+
26
+ ### Fixed
27
+
28
+ - Fix value coercion for composed schemas (via #421) (@robhanlon22)
29
+
30
+
31
+ [Compare v1.10.1...v1.10.2](https://github.com/dry-rb/dry-schema/compare/v1.10.1...v1.10.2)
32
+
3
33
  ## 1.10.1 2022-08-22
4
34
 
5
35
 
@@ -194,7 +224,7 @@ This release ships with a bunch of internal refactorings that should improve per
194
224
 
195
225
  [Compare v1.5.4...v1.5.5](https://github.com/dry-rb/dry-schema/compare/v1.5.4...v1.5.5)
196
226
 
197
- ## 1.5.4
227
+ ## 1.5.4
198
228
 
199
229
  2020-09-03
200
230
 
data/dry-schema.gemspec CHANGED
@@ -38,7 +38,7 @@ Gem::Specification.new do |spec|
38
38
  spec.add_runtime_dependency "dry-configurable", "~> 0.13", ">= 0.13.0"
39
39
  spec.add_runtime_dependency "dry-core", "~> 0.5", ">= 0.5"
40
40
  spec.add_runtime_dependency "dry-initializer", "~> 3.0"
41
- spec.add_runtime_dependency "dry-logic", "~> 1.0"
41
+ spec.add_runtime_dependency "dry-logic", "~> 1.2"
42
42
  spec.add_runtime_dependency "dry-types", "~> 1.5"
43
43
 
44
44
  spec.add_development_dependency "bundler"
@@ -288,13 +288,20 @@ module Dry
288
288
 
289
289
  # Return type schema used by the value coercer
290
290
  #
291
- # @return [Dry::Types::Safe]
291
+ # @return [Dry::Types::Lax]
292
292
  #
293
293
  # @api private
294
294
  def type_schema
295
- our_schema = type_registry["hash"].schema(types).lax
296
- schemas = [*parents.map(&:type_schema), our_schema]
297
- schemas.inject { |result, schema| result.schema(schema.to_a) }
295
+ strict_type_schema.lax
296
+ end
297
+
298
+ # Return type schema used when composing subschemas
299
+ #
300
+ # @return [Dry::Types::Schema]
301
+ #
302
+ # @api private
303
+ def strict_type_schema
304
+ type_registry["hash"].schema(types)
298
305
  end
299
306
 
300
307
  # Return a new DSL instance using the same processor type
@@ -316,7 +323,7 @@ module Dry
316
323
  # @api private
317
324
  def set_type(name, spec)
318
325
  type = resolve_type(spec)
319
- meta = {required: false, maybe: type.optional?}
326
+ meta = {required: true, maybe: type.optional?}
320
327
 
321
328
  @types[name] = type.meta(meta)
322
329
  end
@@ -85,6 +85,24 @@ module Dry
85
85
  end
86
86
  end
87
87
 
88
+ # Set type specification and predicates for a maybe value
89
+ #
90
+ # @example
91
+ # required(:name).maybe(:string)
92
+ #
93
+ # @see Macros::Key#value
94
+ #
95
+ # @return [Macros::Key]
96
+ #
97
+ # @api public
98
+ def maybe(*args, **opts, &block)
99
+ extract_type_spec(args, nullable: true) do |*predicates, type_spec:, type_rule:|
100
+ append_macro(Macros::Maybe) do |macro|
101
+ macro.call(*predicates, type_spec: type_spec, type_rule: type_rule, **opts, &block)
102
+ end
103
+ end
104
+ end
105
+
88
106
  # Specify a nested hash without enforced `hash?` type-check
89
107
  #
90
108
  # This is a simpler building block than `hash` macro, use it
@@ -13,12 +13,15 @@ module Dry
13
13
  def call(*predicates, **opts, &block)
14
14
  ensure_valid_predicates(predicates)
15
15
 
16
- if opts[:type_spec] && !filter_empty_string?
17
- value(predicates[0], :filled?, *predicates[1..predicates.size - 1], **opts, &block)
18
- elsif opts[:type_rule]
19
- value(:filled?).value(*predicates, **opts, &block)
20
- else
21
- value(:filled?, *predicates, **opts, &block)
16
+ append_macro(Macros::Value) do |macro|
17
+ if opts[:type_spec] && !filter_empty_string?
18
+ macro.call(predicates[0], :filled?, *predicates[1..predicates.size - 1], **opts,
19
+ &block)
20
+ elsif opts[:type_rule]
21
+ macro.call(:filled?).value(*predicates, **opts, &block)
22
+ else
23
+ macro.call(:filled?, *predicates, **opts, &block)
24
+ end
22
25
  end
23
26
  end
24
27
 
@@ -32,24 +32,6 @@ module Dry
32
32
  end
33
33
  ruby2_keywords(:filter) if respond_to?(:ruby2_keywords, true)
34
34
 
35
- # Set type specification and predicates for a maybe value
36
- #
37
- # @example
38
- # required(:name).maybe(:string)
39
- #
40
- # @see Macros::Key#value
41
- #
42
- # @return [Macros::Key]
43
- #
44
- # @api public
45
- def maybe(*args, **opts, &block)
46
- extract_type_spec(args, nullable: true) do |*predicates, type_spec:, type_rule:|
47
- append_macro(Macros::Maybe) do |macro|
48
- macro.call(*predicates, type_spec: type_spec, type_rule: type_rule, **opts, &block)
49
- end
50
- end
51
- end
52
-
53
35
  # Coerce macro to a rule
54
36
  #
55
37
  # @return [Dry::Logic::Rule]
@@ -19,7 +19,9 @@ module Dry
19
19
  raise ::Dry::Schema::InvalidSchemaError, "Using maybe with nil? predicate is redundant"
20
20
  end
21
21
 
22
- value(*args, **opts, &block)
22
+ append_macro(Macros::Value) do |macro|
23
+ macro.call(*args, **opts, &block)
24
+ end
23
25
 
24
26
  self
25
27
  end
@@ -62,11 +62,11 @@ module Dry
62
62
  schema = definition.call
63
63
  type_schema =
64
64
  if array_type?(parent_type)
65
- build_array_type(parent_type, definition.type_schema)
65
+ build_array_type(parent_type, definition.strict_type_schema)
66
66
  elsif redefined_schema?(args)
67
67
  parent_type.schema(definition.types)
68
68
  else
69
- definition.type_schema
69
+ definition.strict_type_schema
70
70
  end
71
71
  final_type = optional? ? type_schema.optional : type_schema
72
72
 
@@ -30,9 +30,9 @@ module Dry
30
30
 
31
31
  updated_type =
32
32
  if array_type?(current_type)
33
- build_array_type(current_type, schema.type_schema)
33
+ build_array_type(current_type, schema.strict_type_schema)
34
34
  else
35
- schema.type_schema
35
+ schema.strict_type_schema
36
36
  end
37
37
 
38
38
  import_steps(schema)
@@ -138,13 +138,22 @@ module Dry
138
138
 
139
139
  # Return the type schema
140
140
  #
141
- # @return [Dry::Types::Safe]
141
+ # @return [Dry::Types::Lax]
142
142
  #
143
143
  # @api private
144
144
  def type_schema
145
145
  steps.type_schema
146
146
  end
147
147
 
148
+ # Return type schema used when composing subschemas
149
+ #
150
+ # @return [Dry::Types::Schema]
151
+ #
152
+ # @api private
153
+ def strict_type_schema
154
+ schema_dsl.strict_type_schema
155
+ end
156
+
148
157
  # Return the rule applier
149
158
  #
150
159
  # @api private
@@ -27,34 +27,34 @@ module Dry
27
27
 
28
28
  # @api private
29
29
  def call
30
- handlers.fetch(op_class).call
30
+ if op_class <= Dry::Logic::Operations::Or
31
+ merge_or
32
+ elsif op_class <= Dry::Logic::Operations::And
33
+ merge_and
34
+ elsif op_class <= Dry::Logic::Operations::Implication
35
+ merge_implication
36
+ else
37
+ raise ArgumentError, <<~MESSAGE
38
+ Can't merge operations, op_class=#{op_class}
39
+ MESSAGE
40
+ end
31
41
  end
32
42
 
33
43
  private
34
44
 
35
45
  # @api private
36
- def handlers
37
- @handlers ||=
38
- {
39
- Dry::Logic::Operations::Or => method(:handle_or),
40
- Dry::Logic::Operations::And => method(:handle_and),
41
- Dry::Logic::Operations::Implication => method(:handle_implication)
42
- }
43
- end
44
-
45
- # @api private
46
- def handle_or
46
+ def merge_or
47
47
  old | new
48
48
  end
49
49
 
50
50
  # @api private
51
- def handle_ordered
51
+ def merge_ordered
52
52
  return old if old == new
53
53
 
54
54
  unwrapped_old, old_rule = unwrap_type(old)
55
55
  unwrapped_new, new_rule = unwrap_type(new)
56
56
 
57
- type = merge_underlying_types(unwrapped_old, unwrapped_new)
57
+ type = merge_unwrapped_types(unwrapped_old, unwrapped_new)
58
58
 
59
59
  rule = [old_rule, new_rule].compact.reduce { op_class.new(_1, _2) }
60
60
 
@@ -63,32 +63,44 @@ module Dry
63
63
  type
64
64
  end
65
65
 
66
- alias_method :handle_and, :handle_ordered
67
- alias_method :handle_implication, :handle_ordered
66
+ alias_method :merge_and, :merge_ordered
67
+ alias_method :merge_implication, :merge_ordered
68
68
 
69
69
  # @api private
70
- def merge_underlying_types(unwrapped_old, unwrapped_new)
70
+ def merge_unwrapped_types(unwrapped_old, unwrapped_new)
71
71
  case [unwrapped_old, unwrapped_new]
72
72
  in Dry::Types::Schema, Dry::Types::Schema
73
- types_merger.type_registry["hash"].schema(
74
- types_merger.call(
75
- op_class,
76
- unwrapped_old.name_key_map,
77
- unwrapped_new.name_key_map
78
- )
79
- )
73
+ merge_schemas(unwrapped_old, unwrapped_new)
80
74
  in [Dry::Types::AnyClass, _] | [Dry::Types::Hash, Dry::Types::Schema]
81
75
  unwrapped_new
82
- in [Dry::Types::Hash, Dry::Types::Schema] | [_, Dry::Types::AnyClass]
76
+ in [Dry::Types::Schema, Dry::Types::Hash] | [_, Dry::Types::AnyClass]
83
77
  unwrapped_old
84
78
  else
85
- if unwrapped_old.primitive != unwrapped_new.primitive
86
- raise ArgumentError, <<~MESSAGE
87
- Can't merge types, unwrapped_old=#{unwrapped_old.inspect}, unwrapped_new=#{unwrapped_new.inspect}
88
- MESSAGE
89
- end
79
+ merge_equivalent_types(unwrapped_old, unwrapped_new)
80
+ end
81
+ end
90
82
 
83
+ # @api private
84
+ def merge_schemas(unwrapped_old, unwrapped_new)
85
+ types_merger.type_registry["hash"].schema(
86
+ types_merger.call(
87
+ op_class,
88
+ unwrapped_old.name_key_map,
89
+ unwrapped_new.name_key_map
90
+ )
91
+ )
92
+ end
93
+
94
+ # @api private
95
+ def merge_equivalent_types(unwrapped_old, unwrapped_new)
96
+ if unwrapped_old.primitive <= unwrapped_new.primitive
97
+ unwrapped_new
98
+ elsif unwrapped_new.primitive <= unwrapped_old.primitive
91
99
  unwrapped_old
100
+ else
101
+ raise ArgumentError, <<~MESSAGE
102
+ Can't merge types, unwrapped_old=#{unwrapped_old.inspect}, unwrapped_new=#{unwrapped_new.inspect}
103
+ MESSAGE
92
104
  end
93
105
  end
94
106
 
@@ -96,13 +108,15 @@ module Dry
96
108
  def unwrap_type(type)
97
109
  rules = []
98
110
 
99
- while type.is_a?(Dry::Types::Decorator)
100
- rules << type.rule if type.is_a?(Dry::Types::Constrained)
111
+ loop do
112
+ rules << type.rule if type.respond_to?(:rule)
101
113
 
102
- if type.meta[:maybe] & type.respond_to?(:right)
103
- type = type.right
104
- else
114
+ if type.optional?
115
+ type = type.left.primitive?(nil) ? type.right : type.left
116
+ elsif type.is_a?(Dry::Types::Decorator)
105
117
  type = type.type
118
+ else
119
+ break
106
120
  end
107
121
  end
108
122
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dry
4
4
  module Schema
5
- VERSION = "1.10.1"
5
+ VERSION = "1.10.4"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.1
4
+ version: 1.10.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-22 00:00:00.000000000 Z
11
+ date: 2022-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -84,14 +84,14 @@ dependencies:
84
84
  requirements:
85
85
  - - "~>"
86
86
  - !ruby/object:Gem::Version
87
- version: '1.0'
87
+ version: '1.2'
88
88
  type: :runtime
89
89
  prerelease: false
90
90
  version_requirements: !ruby/object:Gem::Requirement
91
91
  requirements:
92
92
  - - "~>"
93
93
  - !ruby/object:Gem::Version
94
- version: '1.0'
94
+ version: '1.2'
95
95
  - !ruby/object:Gem::Dependency
96
96
  name: dry-types
97
97
  requirement: !ruby/object:Gem::Requirement