dry-types-tuple 0.3.1 → 0.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: d045e436a8d045af55c65dd3278b67ef1c07fd90971ceea8a3fa2bf7e39279d9
4
- data.tar.gz: 769f6744fe426662e65f4f6c8314f4d62f41f1f73b700ab4a39d992f6faf298a
3
+ metadata.gz: 79f57bc1de003bce8abb343b5335af356aaec2a8a2b292ea07d5738ab26a6f34
4
+ data.tar.gz: cb76860dc5f9c0625fe1f31ab9977c4417329c5a9a93126bd8974d5d7dab4e09
5
5
  SHA512:
6
- metadata.gz: 7ca8466bb3dfbae6b6d7265bd1f84d7c930747748476c0b1c3c7d1ee6894e08e5f753ac35dc5f6902657ad438d135b39fd31b78433983e73cb57abafb6fdf58a
7
- data.tar.gz: 1a558eebab32a111fbcb8899b524cfc74a9fba7b901c98dcb4c4084cdff76847b6692fe7e21b0f31a62b01834e934ea4c1150c52a749552e05a90f923e2c7e1b
6
+ metadata.gz: beb9c8e509014a76d91327e3eeba59d35fb3e66f833384480ef05a63a426497e479ba0493c057fa7134cdc87117e794e88de4e84329bfed0f5ff347774f9035b
7
+ data.tar.gz: 882be3b1c04acaa62d974eed786521083e07ae3969c549b8612f7448dbfde6da995c1f24c048dea16bca5c60b7439053bb67a86701d0a324010ab7b35ad0c57d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.4.0 2025-07-02
2
+
3
+ - Better matching of sums and complex tuples by `Dry::Types[…]` inferrer.
4
+ - Add more specs for inferrer; bit of rework in specs in general.
5
+
1
6
  ## 0.3.1 2025-06-26
2
7
 
3
8
  - Change minimal ruby version to 3.1
@@ -5,14 +5,14 @@ module Dry
5
5
  module TypeCoercer
6
6
  module_function
7
7
 
8
- # @overload Coercer.call(array)
8
+ # @overload TypeCoercer.call(array)
9
9
  # @param array [Array<Mixed>]
10
- # @overload Coercer.call(input)
10
+ # @overload TypeCoercer.call(input)
11
11
  # @param tuple [Dry::Types::Tuple]
12
- # @overload Coercer.call(type)
12
+ # @overload TypeCoercer.call(type)
13
13
  # @param type [Dry::Types::Constrained]
14
14
  # @example Usage
15
- # Dry::Types::Tuple::Coercer.([Dry::Types['any'], Dry::Types['string']])
15
+ # Dry::Tuple::TypeCoercer.([Dry::Types['any'], Dry::Types['string']])
16
16
  def call(input, returns: Undefined)
17
17
  case input when Array
18
18
  Dry::Types::Tuple.coerce(input)
@@ -27,7 +27,7 @@ module Dry
27
27
 
28
28
  # @see Tuple.coerce
29
29
  # @example Usage
30
- # Dry::Types::Tuple::Coercer[Dry::Types['any'], Dry::Types['string']]
30
+ # Dry::Tuple::TypeCoercer[Dry::Types['any'], Dry::Types['string']]
31
31
  def [](*input, **opts)
32
32
  call(input, **opts)
33
33
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dry
4
4
  module Tuple
5
- VERSION = '0.3.1'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  end
data/lib/dry/tuple.rb CHANGED
@@ -33,14 +33,12 @@ module Dry
33
33
  @loader ||=
34
34
  ::Zeitwerk::Loader.new.tap do |loader|
35
35
  root = ::File.expand_path("..", __dir__)
36
- warn root
37
36
  loader.tag = "dry-types-tuple"
38
37
  loader.inflector = ::Zeitwerk::GemInflector.new("#{root}/dry-types-tuple.rb")
39
38
  loader.push_dir root
40
39
  loader.ignore \
41
40
  "#{root}/dry-types-tuple.rb",
42
41
  "#{root}/dry/types",
43
- # "#{root}/dry/tuple.rb",
44
42
  "#{root}/dry/tuple/{struct,version}.rb"
45
43
 
46
44
  if defined?(Pry)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "dry/tuple"
4
+
3
5
  module Dry
4
6
  module Types
5
7
  # @example
@@ -221,35 +223,56 @@ module Dry
221
223
  register "coercible.tuple", nominal_tuple.constructor(Kernel.method(:Array))
222
224
  register "params.tuple", nominal_tuple.constructor(Coercions::Params.method(:to_ary))
223
225
 
224
- TUPLE_PREFIX_REGEX = /(?:(?:coercible|nominal|params|strict)\.)?tuple(?=\<)/
225
- TUPLE_MEMBERS_REGEX = /(?<=tuple<).+(?=>)/
226
- TUPLE_MEMBERS_SCAN_REGEX = /(tuple\<(?:\g<1>\,)*\g<1>\>|\[(\g<1>)\](?=$)|[^,]+)(?=,|$)/
227
- SUM_MATCH_REGEX = /((?:(?:\A|\|)(?:[^\|]+))*)\|([^\|]+)\z/
226
+ TUPLE_TYPE_SPEC_REGEX = /\A((?:(?:coercible|nominal|params|strict)\.)?tuple)\<(.+)\>\z/
227
+ TUPLE_MEMBERS_SCAN_REGEX = /(?<=\A|,)(tuple\<(?:\g<1>\,)*\g<1>\>|\[(\g<1>)\](?=$)|[^,]+)(?=,|\z)/
228
228
 
229
229
  # @api private
230
- module ReferenceHook
230
+ # Patch for {Dry::Types.[]} inferrer, that adds support for `tuple<type,types…,[rest]>` syntax
231
+ # to compose {Dry::Types::Tuple} types.
232
+ module ReferenceHookToMatchTuple
233
+ # Wraps over the original method.
234
+ # @see Dry::Types.[]
235
+ # @return [Dry::Types::Type]
231
236
  def [](name)
232
- case name
233
- when TUPLE_PREFIX_REGEX
234
- type_map.fetch_or_store(name) do
235
- key = Regexp.last_match[0]
236
- types =
237
- name[TUPLE_MEMBERS_REGEX].
238
- scan(TUPLE_MEMBERS_SCAN_REGEX).
239
- map { |(type, rest)| rest.nil? ? self[type] : [self[rest]] }
240
- super(key).of(*types)
237
+ type_map.fetch_or_store(name) do
238
+ if tuple_match = name.match(TUPLE_TYPE_SPEC_REGEX)
239
+ type_id, members = tuple_match[1..2]
240
+ types = members.scan(TUPLE_MEMBERS_SCAN_REGEX).map do |(type, rest)|
241
+ rest.nil? ? self[type] : [self[rest]]
242
+ end
243
+
244
+ super(type_id).of(*types)
245
+ else
246
+ super
241
247
  end
242
- when SUM_MATCH_REGEX
243
- type_map.fetch_or_store(name) do
244
- left, right = Regexp.last_match.captures
245
- self[left] | super(right)
248
+ end
249
+ end
250
+ end
251
+
252
+ singleton_class.prepend ReferenceHookToMatchTuple
253
+
254
+ SUM_MATCH_REGEX = /(?<=\A)(.+)\|(?!\w+[\>\],])([^\|]+)\z/
255
+
256
+ # @api private
257
+ # Patch for {Dry::Types.[]} inferrer, that adds support for `type|type|…` syntax
258
+ # to compose {Dry::Types::Sum} types.
259
+ module ReferenceHookToMatchSum
260
+ # Wraps over the previously hooked method.
261
+ # @see Dry::Types::ReferenceHookToMatchTuple#[]
262
+ # @see Dry::Types.[]
263
+ # @return [Dry::Types::Type]
264
+ def [](name)
265
+ type_map.fetch_or_store(name) do
266
+ if sum_match = name.match(SUM_MATCH_REGEX)
267
+ left, right = sum_match.captures
268
+ self[left] | self[right]
269
+ else
270
+ super
246
271
  end
247
- else
248
- super(name)
249
272
  end
250
273
  end
251
274
  end
252
275
 
253
- singleton_class.prepend ReferenceHook
276
+ singleton_class.prepend ReferenceHookToMatchSum
254
277
  end
255
278
  end
@@ -1,4 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/tuple"
4
3
  require "dry/types/tuple"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-types-tuple
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton Semenov