dry-types 1.6.0 → 1.7.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 +4 -4
- data/CHANGELOG.md +20 -0
- data/dry-types.gemspec +3 -5
- data/lib/dry/types/builder.rb +39 -2
- data/lib/dry/types/composition.rb +152 -0
- data/lib/dry/types/container.rb +1 -3
- data/lib/dry/types/extensions/maybe.rb +7 -2
- data/lib/dry/types/extensions/monads.rb +7 -2
- data/lib/dry/types/implication.rb +66 -0
- data/lib/dry/types/intersection.rb +108 -0
- data/lib/dry/types/module.rb +7 -3
- data/lib/dry/types/predicate_registry.rb +7 -20
- data/lib/dry/types/printer/composition.rb +44 -0
- data/lib/dry/types/printer.rb +110 -129
- data/lib/dry/types/sum.rb +3 -91
- data/lib/dry/types/version.rb +1 -1
- data/lib/dry/types.rb +9 -3
- metadata +26 -50
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fdd7e08f86f3137ead67bb6170e91de625227e97783be335b982e5a4c313b32e
|
4
|
+
data.tar.gz: faa51ae68eb4942cb64520eed7d6c4dbf5b46af384a91acdfc94105f32298839
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 588feadceca555b168266b6e6ee542d71b154152ea56a88f7b601c33a79b116c90b86356e03bc8ca273e4df5d38e4056277c88502387e836bba4af8409fede14
|
7
|
+
data.tar.gz: 72326eb3f32d33cbc95d1e20d6bec4f1bc40a66fa6cac818d35b8ff2214d3932f3350d5e6cf36a6a49ea3ffd862d7422a49622d5a98937a0be6f914d0f390965
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
<!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
|
2
2
|
|
3
|
+
## 1.7.0 2022-11-04
|
4
|
+
|
5
|
+
|
6
|
+
### Changed
|
7
|
+
|
8
|
+
- This version is compatible with recently released dry-rb dependencies (@flash-gordon)
|
9
|
+
- Updated to dry-core 1.0 (@flash-gordon + @solnic)
|
10
|
+
- Dependency on dry-container was dropped (@flash-gordon)
|
11
|
+
|
12
|
+
[Compare v1.6.1...v1.7.0](https://github.com/dry-rb/dry-types/compare/v1.6.1...v1.7.0)
|
13
|
+
|
14
|
+
## 1.6.1 2022-10-15
|
15
|
+
|
16
|
+
|
17
|
+
### Changed
|
18
|
+
|
19
|
+
- Fix issues with internal const_missing and Inflector/Module constants (@flash-gordon + @solnic)
|
20
|
+
|
21
|
+
[Compare v1.6.0...v1.6.1](https://github.com/dry-rb/dry-types/compare/v1.6.0...v1.6.1)
|
22
|
+
|
3
23
|
## 1.6.0 2022-10-15
|
4
24
|
|
5
25
|
|
data/dry-types.gemspec
CHANGED
@@ -30,14 +30,12 @@ Gem::Specification.new do |spec|
|
|
30
30
|
|
31
31
|
# to update dependencies edit project.yml
|
32
32
|
spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
|
33
|
-
spec.add_runtime_dependency "dry-
|
34
|
-
spec.add_runtime_dependency "dry-
|
35
|
-
spec.add_runtime_dependency "dry-
|
36
|
-
spec.add_runtime_dependency "dry-logic", "~> 1.3", ">= 1.3"
|
33
|
+
spec.add_runtime_dependency "dry-core", "~> 1.0", "< 2"
|
34
|
+
spec.add_runtime_dependency "dry-inflector", "~> 1.0", "< 2"
|
35
|
+
spec.add_runtime_dependency "dry-logic", ">= 1.4", "< 2"
|
37
36
|
spec.add_runtime_dependency "zeitwerk", "~> 2.6"
|
38
37
|
|
39
38
|
spec.add_development_dependency "bundler"
|
40
|
-
spec.add_development_dependency "dry-monads", "~> 1.0"
|
41
39
|
spec.add_development_dependency "rake"
|
42
40
|
spec.add_development_dependency "rspec"
|
43
41
|
spec.add_development_dependency "yard"
|
data/lib/dry/types/builder.rb
CHANGED
@@ -5,6 +5,7 @@ module Dry
|
|
5
5
|
# Common API for building types and composition
|
6
6
|
#
|
7
7
|
# @api public
|
8
|
+
# rubocop:disable Metrics/ModuleLength
|
8
9
|
module Builder
|
9
10
|
include Dry::Core::Constants
|
10
11
|
|
@@ -30,8 +31,29 @@ module Dry
|
|
30
31
|
#
|
31
32
|
# @api private
|
32
33
|
def |(other)
|
33
|
-
|
34
|
-
|
34
|
+
compose(other, Sum)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Compose two types into an Intersection type
|
38
|
+
#
|
39
|
+
# @param [Type] other
|
40
|
+
#
|
41
|
+
# @return [Intersection, Intersection::Constrained]
|
42
|
+
#
|
43
|
+
# @api private
|
44
|
+
def &(other)
|
45
|
+
compose(other, Intersection)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Compose two types into an Implication type
|
49
|
+
#
|
50
|
+
# @param [Type] other
|
51
|
+
#
|
52
|
+
# @return [Implication, Implication::Constrained]
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
def >(other)
|
56
|
+
compose(other, Implication)
|
35
57
|
end
|
36
58
|
|
37
59
|
# Turn a type into an optional type
|
@@ -179,6 +201,21 @@ module Dry
|
|
179
201
|
end
|
180
202
|
end
|
181
203
|
end
|
204
|
+
|
205
|
+
private
|
206
|
+
|
207
|
+
# @api private
|
208
|
+
def compose(other, composition_class)
|
209
|
+
klass =
|
210
|
+
if constrained? && other.constrained?
|
211
|
+
composition_class::Constrained
|
212
|
+
else
|
213
|
+
composition_class
|
214
|
+
end
|
215
|
+
|
216
|
+
klass.new(self, other)
|
217
|
+
end
|
182
218
|
end
|
219
|
+
# rubocop:enable Metrics/ModuleLength
|
183
220
|
end
|
184
221
|
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/core/equalizer"
|
4
|
+
require "dry/types/options"
|
5
|
+
require "dry/types/meta"
|
6
|
+
|
7
|
+
module Dry
|
8
|
+
module Types
|
9
|
+
module Composition
|
10
|
+
include Type
|
11
|
+
include Builder
|
12
|
+
include Options
|
13
|
+
include Meta
|
14
|
+
include Printable
|
15
|
+
include Dry::Equalizer(:left, :right, :options, :meta, inspect: false, immutable: true)
|
16
|
+
|
17
|
+
# @return [Type]
|
18
|
+
attr_reader :left
|
19
|
+
|
20
|
+
# @return [Type]
|
21
|
+
attr_reader :right
|
22
|
+
|
23
|
+
module Constrained
|
24
|
+
def rule
|
25
|
+
left.rule.public_send(self.class.operator, right.rule)
|
26
|
+
end
|
27
|
+
|
28
|
+
def constrained?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.included(base)
|
34
|
+
composition_name = Inflector.demodulize(base)
|
35
|
+
ast_type = Inflector.underscore(composition_name).to_sym
|
36
|
+
base.define_singleton_method(:ast_type) { ast_type }
|
37
|
+
base.define_singleton_method(:composition_name) { composition_name }
|
38
|
+
base.const_set("Constrained", Class.new(base) { include Constrained })
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param [Type] left
|
42
|
+
# @param [Type] right
|
43
|
+
# @param [Hash] options
|
44
|
+
#
|
45
|
+
# @api private
|
46
|
+
def initialize(left, right, **options)
|
47
|
+
super
|
48
|
+
@left, @right = left, right
|
49
|
+
freeze
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [String]
|
53
|
+
#
|
54
|
+
# @api public
|
55
|
+
def name
|
56
|
+
[left, right].map(&:name).join(" #{self.class.operator} ")
|
57
|
+
end
|
58
|
+
|
59
|
+
# @return [false]
|
60
|
+
#
|
61
|
+
# @api public
|
62
|
+
def default?
|
63
|
+
false
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [false]
|
67
|
+
#
|
68
|
+
# @api public
|
69
|
+
def constrained?
|
70
|
+
false
|
71
|
+
end
|
72
|
+
|
73
|
+
# @return [Boolean]
|
74
|
+
#
|
75
|
+
# @api public
|
76
|
+
def optional?
|
77
|
+
false
|
78
|
+
end
|
79
|
+
|
80
|
+
# @param [Object] input
|
81
|
+
#
|
82
|
+
# @return [Object]
|
83
|
+
#
|
84
|
+
# @api private
|
85
|
+
def call_unsafe(input)
|
86
|
+
raise NotImplementedError
|
87
|
+
end
|
88
|
+
|
89
|
+
# @param [Object] input
|
90
|
+
#
|
91
|
+
# @return [Object]
|
92
|
+
#
|
93
|
+
# @api private
|
94
|
+
def call_safe(input, &block)
|
95
|
+
raise NotImplementedError
|
96
|
+
end
|
97
|
+
|
98
|
+
# @param [Object] input
|
99
|
+
#
|
100
|
+
# @api public
|
101
|
+
def try(input)
|
102
|
+
raise NotImplementedError
|
103
|
+
end
|
104
|
+
|
105
|
+
# @api private
|
106
|
+
def success(input)
|
107
|
+
result = try(input)
|
108
|
+
if result.success?
|
109
|
+
result
|
110
|
+
else
|
111
|
+
raise ArgumentError, "Invalid success value '#{input}' for #{inspect}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# @api private
|
116
|
+
def failure(input, _error = nil)
|
117
|
+
result = try(input)
|
118
|
+
if result.failure?
|
119
|
+
result
|
120
|
+
else
|
121
|
+
raise ArgumentError, "Invalid failure value '#{input}' for #{inspect}"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# @param [Object] value
|
126
|
+
#
|
127
|
+
# @return [Boolean]
|
128
|
+
#
|
129
|
+
# @api private
|
130
|
+
def primitive?(value)
|
131
|
+
raise NotImplementedError
|
132
|
+
end
|
133
|
+
|
134
|
+
# @see Nominal#to_ast
|
135
|
+
#
|
136
|
+
# @api public
|
137
|
+
def to_ast(meta: true)
|
138
|
+
[self.class.ast_type,
|
139
|
+
[left.to_ast(meta: meta), right.to_ast(meta: meta), meta ? self.meta : EMPTY_HASH]]
|
140
|
+
end
|
141
|
+
|
142
|
+
# Wrap the type with a proc
|
143
|
+
#
|
144
|
+
# @return [Proc]
|
145
|
+
#
|
146
|
+
# @api public
|
147
|
+
def to_proc
|
148
|
+
proc { |value| self.(value) }
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
data/lib/dry/types/container.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/container"
|
4
|
-
|
5
3
|
module Dry
|
6
4
|
module Types
|
7
5
|
# Internal container for the built-in types
|
8
6
|
#
|
9
7
|
# @api private
|
10
8
|
class Container
|
11
|
-
include
|
9
|
+
include Core::Container::Mixin
|
12
10
|
end
|
13
11
|
end
|
14
12
|
end
|
@@ -1,6 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/monads
|
3
|
+
require "dry/monads"
|
4
|
+
require "dry/monads/version"
|
5
|
+
|
6
|
+
if Gem::Version.new(Dry::Monads::VERSION) < Gem::Version.new("1.5.0")
|
7
|
+
raise "dry-types requires dry-monads >= 1.5.0"
|
8
|
+
end
|
4
9
|
|
5
10
|
module Dry
|
6
11
|
module Types
|
@@ -13,7 +18,7 @@ module Dry
|
|
13
18
|
include Decorator
|
14
19
|
include Builder
|
15
20
|
include Printable
|
16
|
-
include ::Dry::Monads
|
21
|
+
include ::Dry::Monads[:maybe]
|
17
22
|
|
18
23
|
# @param [Dry::Monads::Maybe, Object] input
|
19
24
|
#
|
@@ -1,6 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/monads
|
3
|
+
require "dry/monads"
|
4
|
+
require "dry/monads/version"
|
5
|
+
|
6
|
+
if Gem::Version.new(Dry::Monads::VERSION) < Gem::Version.new("1.5.0")
|
7
|
+
raise "dry-types requires dry-monads >= 1.5.0"
|
8
|
+
end
|
4
9
|
|
5
10
|
module Dry
|
6
11
|
module Types
|
@@ -8,7 +13,7 @@ module Dry
|
|
8
13
|
#
|
9
14
|
# @api public
|
10
15
|
class Result
|
11
|
-
include Dry::Monads
|
16
|
+
include ::Dry::Monads[:result]
|
12
17
|
|
13
18
|
# Turn result into a monad
|
14
19
|
#
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
module Types
|
5
|
+
# Implication type
|
6
|
+
#
|
7
|
+
# @api public
|
8
|
+
class Implication
|
9
|
+
include Composition
|
10
|
+
|
11
|
+
def self.operator
|
12
|
+
:>
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param [Object] input
|
16
|
+
#
|
17
|
+
# @return [Object]
|
18
|
+
#
|
19
|
+
# @api private
|
20
|
+
def call_unsafe(input)
|
21
|
+
if left.try(input).success?
|
22
|
+
right.call_unsafe(input)
|
23
|
+
else
|
24
|
+
input
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param [Object] input
|
29
|
+
#
|
30
|
+
# @return [Object]
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
def call_safe(input, &block)
|
34
|
+
if left.try(input).success?
|
35
|
+
right.call_safe(input, &block)
|
36
|
+
else
|
37
|
+
input
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param [Object] input
|
42
|
+
#
|
43
|
+
# @api public
|
44
|
+
def try(input)
|
45
|
+
if left.try(input).success?
|
46
|
+
right.try(input)
|
47
|
+
else
|
48
|
+
Result::Success.new(input)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# @param [Object] value
|
53
|
+
#
|
54
|
+
# @return [Boolean]
|
55
|
+
#
|
56
|
+
# @api private
|
57
|
+
def primitive?(value)
|
58
|
+
if left.primitive?(value)
|
59
|
+
right.primitive?(value)
|
60
|
+
else
|
61
|
+
true
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/core/equalizer"
|
4
|
+
require "dry/types/options"
|
5
|
+
require "dry/types/meta"
|
6
|
+
|
7
|
+
module Dry
|
8
|
+
module Types
|
9
|
+
# Intersection type
|
10
|
+
#
|
11
|
+
# @api public
|
12
|
+
class Intersection
|
13
|
+
include Composition
|
14
|
+
|
15
|
+
def self.operator
|
16
|
+
:&
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param [Object] input
|
20
|
+
#
|
21
|
+
# @return [Object]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
def call_unsafe(input)
|
25
|
+
merge_results(left.call_unsafe(input), right.call_unsafe(input))
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param [Object] input
|
29
|
+
#
|
30
|
+
# @return [Object]
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
def call_safe(input, &block)
|
34
|
+
try_sides(input, &block).input
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param [Object] input
|
38
|
+
#
|
39
|
+
# @api public
|
40
|
+
def try(input)
|
41
|
+
try_sides(input) do |failure|
|
42
|
+
if block_given?
|
43
|
+
yield(failure)
|
44
|
+
else
|
45
|
+
failure
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# @param [Object] value
|
51
|
+
#
|
52
|
+
# @return [Boolean]
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
def primitive?(value)
|
56
|
+
left.primitive?(value) && right.primitive?(value)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# @api private
|
62
|
+
def try_sides(input, &block)
|
63
|
+
results = []
|
64
|
+
|
65
|
+
[left, right].each do |side|
|
66
|
+
result = try_side(side, input, &block)
|
67
|
+
return result if result.failure?
|
68
|
+
|
69
|
+
results << result
|
70
|
+
end
|
71
|
+
|
72
|
+
Result::Success.new(merge_results(*results.map(&:input)))
|
73
|
+
end
|
74
|
+
|
75
|
+
# @api private
|
76
|
+
def try_side(side, input)
|
77
|
+
failure = nil
|
78
|
+
|
79
|
+
result = side.try(input) do |f|
|
80
|
+
failure = f
|
81
|
+
yield(f)
|
82
|
+
end
|
83
|
+
|
84
|
+
if result.is_a?(Result)
|
85
|
+
result
|
86
|
+
elsif failure
|
87
|
+
Result::Failure.new(result, failure)
|
88
|
+
else
|
89
|
+
Result::Success.new(result)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# @api private
|
94
|
+
def merge_results(left_result, right_result)
|
95
|
+
case left_result
|
96
|
+
when ::Array
|
97
|
+
left_result
|
98
|
+
.zip(right_result)
|
99
|
+
.map { |lhs, rhs| merge_results(lhs, rhs) }
|
100
|
+
when ::Hash
|
101
|
+
left_result.merge(right_result)
|
102
|
+
else
|
103
|
+
left_result
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/lib/dry/types/module.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "dry/types/builder_methods"
|
4
|
+
|
3
5
|
module Dry
|
4
6
|
module Types
|
5
7
|
# Export types registered in a container as module constants.
|
@@ -44,7 +46,7 @@ module Dry
|
|
44
46
|
elsif Undefined.equal?(default)
|
45
47
|
default_ns = Undefined
|
46
48
|
else
|
47
|
-
default_ns = Inflector.camelize(default).to_sym
|
49
|
+
default_ns = Types::Inflector.camelize(default).to_sym
|
48
50
|
end
|
49
51
|
|
50
52
|
tree = registry_tree
|
@@ -52,7 +54,9 @@ module Dry
|
|
52
54
|
if namespaces.empty? && aliases.empty?
|
53
55
|
modules = tree.select { |_, v| v.is_a?(::Hash) }.map(&:first)
|
54
56
|
else
|
55
|
-
modules = (namespaces + aliases.keys).map { |n|
|
57
|
+
modules = (namespaces + aliases.keys).map { |n|
|
58
|
+
Types::Inflector.camelize(n).to_sym
|
59
|
+
}
|
56
60
|
end
|
57
61
|
|
58
62
|
tree.each_with_object({}) do |(key, value), constants|
|
@@ -73,7 +77,7 @@ module Dry
|
|
73
77
|
@registry_tree ||= @registry.keys.each_with_object({}) { |key, tree|
|
74
78
|
type = @registry[key]
|
75
79
|
*modules, const_name = key.split(".").map { |part|
|
76
|
-
Inflector.camelize(part).to_sym
|
80
|
+
Types::Inflector.camelize(part).to_sym
|
77
81
|
}
|
78
82
|
next if modules.empty?
|
79
83
|
|
@@ -15,27 +15,14 @@ module Dry
|
|
15
15
|
KERNEL_RESPOND_TO = ::Kernel.instance_method(:respond_to?)
|
16
16
|
private_constant(:KERNEL_RESPOND_TO)
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
# @api private
|
25
|
-
def key?(name)
|
26
|
-
KERNEL_RESPOND_TO.bind_call(@predicates, name)
|
27
|
-
end
|
28
|
-
else
|
29
|
-
# @api private
|
30
|
-
def initialize(predicates = Logic::Predicates)
|
31
|
-
@predicates = predicates
|
32
|
-
@has_predicate = KERNEL_RESPOND_TO.bind(@predicates)
|
33
|
-
end
|
18
|
+
# @api private
|
19
|
+
def initialize(predicates = Logic::Predicates)
|
20
|
+
@predicates = predicates
|
21
|
+
end
|
34
22
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
23
|
+
# @api private
|
24
|
+
def key?(name)
|
25
|
+
KERNEL_RESPOND_TO.bind_call(@predicates, name)
|
39
26
|
end
|
40
27
|
|
41
28
|
# @api private
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
module Types
|
5
|
+
# @api private
|
6
|
+
class Printer
|
7
|
+
# @api private
|
8
|
+
class Composition
|
9
|
+
def initialize(printer, composition_class)
|
10
|
+
@printer = printer
|
11
|
+
@composition_class = composition_class
|
12
|
+
freeze
|
13
|
+
end
|
14
|
+
|
15
|
+
def visit(composition)
|
16
|
+
visit_constructors(composition) do |constructors|
|
17
|
+
@printer.visit_options(composition.options, composition.meta) do |opts|
|
18
|
+
yield "#{@composition_class.composition_name}<#{constructors}#{opts}>"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def visit_constructors(composition)
|
26
|
+
visit_constructor(composition.left) do |left|
|
27
|
+
visit_constructor(composition.right) do |right|
|
28
|
+
yield "#{left} #{@composition_class.operator} #{right}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def visit_constructor(type, &block)
|
34
|
+
case type
|
35
|
+
when @composition_class
|
36
|
+
visit_constructors(type, &block)
|
37
|
+
else
|
38
|
+
@printer.visit(type, &block)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/dry/types/printer.rb
CHANGED
@@ -1,17 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "dry/types/printer/composition"
|
4
|
+
|
3
5
|
module Dry
|
4
6
|
# rubocop:disable Metrics/AbcSize
|
5
7
|
# rubocop:disable Metrics/PerceivedComplexity
|
6
8
|
module Types
|
7
9
|
# @api private
|
8
10
|
class Printer
|
9
|
-
MAPPING = {
|
11
|
+
MAPPING = {
|
10
12
|
Nominal => :visit_nominal,
|
11
13
|
Constructor => :visit_constructor,
|
12
|
-
|
13
|
-
|
14
|
-
|
14
|
+
[
|
15
|
+
Constrained,
|
16
|
+
Constrained::Coercible
|
17
|
+
] => :visit_constrained,
|
18
|
+
Types::Hash => :visit_hash,
|
15
19
|
Schema => :visit_schema,
|
16
20
|
Schema::Key => :visit_key,
|
17
21
|
Map => :visit_map,
|
@@ -19,12 +23,22 @@ module Dry
|
|
19
23
|
Array::Member => :visit_array_member,
|
20
24
|
Lax => :visit_lax,
|
21
25
|
Enum => :visit_enum,
|
22
|
-
Default => :visit_default,
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
+
[Default, Default::Callable] => :visit_default,
|
27
|
+
[
|
28
|
+
Sum,
|
29
|
+
Sum::Constrained,
|
30
|
+
Intersection,
|
31
|
+
Intersection::Constrained,
|
32
|
+
Implication,
|
33
|
+
Implication::Constrained
|
34
|
+
] => :visit_composition,
|
26
35
|
Any.class => :visit_any
|
27
|
-
}
|
36
|
+
}.flat_map { |k, v| Array(k).map { |kk| [kk, v] } }.to_h
|
37
|
+
|
38
|
+
def initialize
|
39
|
+
@composition_printers = {}
|
40
|
+
freeze
|
41
|
+
end
|
28
42
|
|
29
43
|
def call(type)
|
30
44
|
output = "".dup
|
@@ -87,106 +101,10 @@ module Dry
|
|
87
101
|
end
|
88
102
|
end
|
89
103
|
|
90
|
-
def
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
type_fn_str = ""
|
95
|
-
strict_str = ""
|
96
|
-
|
97
|
-
strict_str = "strict " if options.delete(:strict)
|
98
|
-
|
99
|
-
if (key_fn = options.delete(:key_transform_fn))
|
100
|
-
visit_callable(key_fn) do |fn|
|
101
|
-
key_fn_str = "key_fn=#{fn} "
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
if (type_fn = options.delete(:type_transform_fn))
|
106
|
-
visit_callable(type_fn) do |fn|
|
107
|
-
type_fn_str = "type_fn=#{fn} "
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
keys = options.delete(:keys)
|
112
|
-
|
113
|
-
visit_options(options, schema.meta) do |opts|
|
114
|
-
opts = "#{opts[1..]} " unless opts.empty?
|
115
|
-
schema_parameters = "#{key_fn_str}#{type_fn_str}#{strict_str}#{opts}"
|
116
|
-
|
117
|
-
header = "Schema<#{schema_parameters}keys={"
|
118
|
-
|
119
|
-
if size.zero?
|
120
|
-
yield "#{header}}>"
|
121
|
-
else
|
122
|
-
yield header.dup << keys.map { |key|
|
123
|
-
visit(key) { |type| type }
|
124
|
-
}.join(" ") << "}>"
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
def visit_map(map)
|
130
|
-
visit(map.key_type) do |key|
|
131
|
-
visit(map.value_type) do |value|
|
132
|
-
options = map.options.dup
|
133
|
-
options.delete(:key_type)
|
134
|
-
options.delete(:value_type)
|
135
|
-
|
136
|
-
visit_options(options) do |_opts|
|
137
|
-
yield "Map<#{key} => #{value}>"
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def visit_key(key)
|
144
|
-
visit(key.type) do |type|
|
145
|
-
if key.required?
|
146
|
-
yield "#{key.name}: #{type}"
|
147
|
-
else
|
148
|
-
yield "#{key.name}?: #{type}"
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def visit_sum(sum)
|
154
|
-
visit_sum_constructors(sum) do |constructors|
|
155
|
-
visit_options(sum.options, sum.meta) do |opts|
|
156
|
-
yield "Sum<#{constructors}#{opts}>"
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
def visit_sum_constructors(sum)
|
162
|
-
case sum.left
|
163
|
-
when Sum
|
164
|
-
visit_sum_constructors(sum.left) do |left|
|
165
|
-
case sum.right
|
166
|
-
when Sum
|
167
|
-
visit_sum_constructors(sum.right) do |right|
|
168
|
-
yield "#{left} | #{right}"
|
169
|
-
end
|
170
|
-
else
|
171
|
-
visit(sum.right) do |right|
|
172
|
-
yield "#{left} | #{right}"
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
else
|
177
|
-
visit(sum.left) do |left|
|
178
|
-
case sum.right
|
179
|
-
when Sum
|
180
|
-
visit_sum_constructors(sum.right) do |right|
|
181
|
-
yield "#{left} | #{right}"
|
182
|
-
end
|
183
|
-
else
|
184
|
-
visit(sum.right) do |right|
|
185
|
-
yield "#{left} | #{right}"
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
104
|
+
def visit_composition(composition, &block)
|
105
|
+
klass = composition.class
|
106
|
+
@composition_printers[klass] = Composition.new(self, klass)
|
107
|
+
@composition_printers[klass].visit(composition, &block)
|
190
108
|
end
|
191
109
|
|
192
110
|
def visit_enum(enum)
|
@@ -234,25 +152,6 @@ module Dry
|
|
234
152
|
end
|
235
153
|
end
|
236
154
|
|
237
|
-
def visit_hash(hash)
|
238
|
-
options = hash.options.dup
|
239
|
-
type_fn_str = ""
|
240
|
-
|
241
|
-
if (type_fn = options.delete(:type_transform_fn))
|
242
|
-
visit_callable(type_fn) do |fn|
|
243
|
-
type_fn_str = "type_fn=#{fn}"
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
visit_options(options, hash.meta) do |opts|
|
248
|
-
if opts.empty? && type_fn_str.empty?
|
249
|
-
yield "Hash"
|
250
|
-
else
|
251
|
-
yield "Hash<#{type_fn_str}#{opts}>"
|
252
|
-
end
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
155
|
def visit_callable(callable)
|
257
156
|
fn = callable.is_a?(String) ? FnContainer[callable] : callable
|
258
157
|
|
@@ -288,6 +187,88 @@ module Dry
|
|
288
187
|
end
|
289
188
|
end
|
290
189
|
|
190
|
+
def visit_schema(schema)
|
191
|
+
options = schema.options.dup
|
192
|
+
size = schema.count
|
193
|
+
key_fn_str = ""
|
194
|
+
type_fn_str = ""
|
195
|
+
strict_str = ""
|
196
|
+
|
197
|
+
strict_str = "strict " if options.delete(:strict)
|
198
|
+
|
199
|
+
if (key_fn = options.delete(:key_transform_fn))
|
200
|
+
visit_callable(key_fn) do |fn|
|
201
|
+
key_fn_str = "key_fn=#{fn} "
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
if (type_fn = options.delete(:type_transform_fn))
|
206
|
+
visit_callable(type_fn) do |fn|
|
207
|
+
type_fn_str = "type_fn=#{fn} "
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
keys = options.delete(:keys)
|
212
|
+
|
213
|
+
visit_options(options, schema.meta) do |opts|
|
214
|
+
opts = "#{opts[1..]} " unless opts.empty?
|
215
|
+
schema_parameters = "#{key_fn_str}#{type_fn_str}#{strict_str}#{opts}"
|
216
|
+
|
217
|
+
header = "Schema<#{schema_parameters}keys={"
|
218
|
+
|
219
|
+
if size.zero?
|
220
|
+
yield "#{header}}>"
|
221
|
+
else
|
222
|
+
yield header.dup << keys.map { |key|
|
223
|
+
visit(key) { |type| type }
|
224
|
+
}.join(" ") << "}>"
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def visit_map(map)
|
230
|
+
visit(map.key_type) do |key|
|
231
|
+
visit(map.value_type) do |value|
|
232
|
+
options = map.options.dup
|
233
|
+
options.delete(:key_type)
|
234
|
+
options.delete(:value_type)
|
235
|
+
|
236
|
+
visit_options(options) do |_opts|
|
237
|
+
yield "Map<#{key} => #{value}>"
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def visit_key(key)
|
244
|
+
visit(key.type) do |type|
|
245
|
+
if key.required?
|
246
|
+
yield "#{key.name}: #{type}"
|
247
|
+
else
|
248
|
+
yield "#{key.name}?: #{type}"
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def visit_hash(hash)
|
254
|
+
options = hash.options.dup
|
255
|
+
type_fn_str = ""
|
256
|
+
|
257
|
+
if (type_fn = options.delete(:type_transform_fn))
|
258
|
+
visit_callable(type_fn) do |fn|
|
259
|
+
type_fn_str = "type_fn=#{fn}"
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
visit_options(options, hash.meta) do |opts|
|
264
|
+
if opts.empty? && type_fn_str.empty?
|
265
|
+
yield "Hash"
|
266
|
+
else
|
267
|
+
yield "Hash<#{type_fn_str}#{opts}>"
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
291
272
|
def visit_options(options, meta = EMPTY_HASH) # rubocop:disable Metrics/PerceivedComplexity
|
292
273
|
if options.empty? && meta.empty?
|
293
274
|
yield ""
|
@@ -312,7 +293,7 @@ module Dry
|
|
312
293
|
end
|
313
294
|
end
|
314
295
|
|
315
|
-
PRINTER = Printer.new
|
296
|
+
PRINTER = Printer.new
|
316
297
|
end
|
317
298
|
# rubocop:enable Metrics/AbcSize
|
318
299
|
# rubocop:enable Metrics/PerceivedComplexity
|
data/lib/dry/types/sum.rb
CHANGED
@@ -6,62 +6,10 @@ module Dry
|
|
6
6
|
#
|
7
7
|
# @api public
|
8
8
|
class Sum
|
9
|
-
include
|
10
|
-
include Builder
|
11
|
-
include Options
|
12
|
-
include Meta
|
13
|
-
include Printable
|
14
|
-
include Dry::Equalizer(:left, :right, :options, :meta, inspect: false, immutable: true)
|
9
|
+
include Composition
|
15
10
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
# @return [Type]
|
20
|
-
attr_reader :right
|
21
|
-
|
22
|
-
# @api private
|
23
|
-
class Constrained < Sum
|
24
|
-
# @return [Dry::Logic::Operations::Or]
|
25
|
-
def rule
|
26
|
-
left.rule | right.rule
|
27
|
-
end
|
28
|
-
|
29
|
-
# @return [true]
|
30
|
-
def constrained?
|
31
|
-
true
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# @param [Type] left
|
36
|
-
# @param [Type] right
|
37
|
-
# @param [Hash] options
|
38
|
-
#
|
39
|
-
# @api private
|
40
|
-
def initialize(left, right, **options)
|
41
|
-
super
|
42
|
-
@left, @right = left, right
|
43
|
-
freeze
|
44
|
-
end
|
45
|
-
|
46
|
-
# @return [String]
|
47
|
-
#
|
48
|
-
# @api public
|
49
|
-
def name
|
50
|
-
[left, right].map(&:name).join(" | ")
|
51
|
-
end
|
52
|
-
|
53
|
-
# @return [false]
|
54
|
-
#
|
55
|
-
# @api public
|
56
|
-
def default?
|
57
|
-
false
|
58
|
-
end
|
59
|
-
|
60
|
-
# @return [false]
|
61
|
-
#
|
62
|
-
# @api public
|
63
|
-
def constrained?
|
64
|
-
false
|
11
|
+
def self.operator
|
12
|
+
:|
|
65
13
|
end
|
66
14
|
|
67
15
|
# @return [Boolean]
|
@@ -104,26 +52,6 @@ module Dry
|
|
104
52
|
end
|
105
53
|
end
|
106
54
|
|
107
|
-
# @api private
|
108
|
-
def success(input)
|
109
|
-
if left.valid?(input)
|
110
|
-
left.success(input)
|
111
|
-
elsif right.valid?(input)
|
112
|
-
right.success(input)
|
113
|
-
else
|
114
|
-
raise ArgumentError, "Invalid success value '#{input}' for #{inspect}"
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
# @api private
|
119
|
-
def failure(input, _error = nil)
|
120
|
-
if left.valid?(input)
|
121
|
-
right.failure(input, right.try(input).error)
|
122
|
-
else
|
123
|
-
left.failure(input, left.try(input).error)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
55
|
# @param [Object] value
|
128
56
|
#
|
129
57
|
# @return [Boolean]
|
@@ -149,13 +77,6 @@ module Dry
|
|
149
77
|
end
|
150
78
|
end
|
151
79
|
|
152
|
-
# @see Nominal#to_ast
|
153
|
-
#
|
154
|
-
# @api public
|
155
|
-
def to_ast(meta: true)
|
156
|
-
[:sum, [left.to_ast(meta: meta), right.to_ast(meta: meta), meta ? self.meta : EMPTY_HASH]]
|
157
|
-
end
|
158
|
-
|
159
80
|
# @param [Hash] options
|
160
81
|
#
|
161
82
|
# @return [Constrained,Sum]
|
@@ -170,15 +91,6 @@ module Dry
|
|
170
91
|
super
|
171
92
|
end
|
172
93
|
end
|
173
|
-
|
174
|
-
# Wrap the type with a proc
|
175
|
-
#
|
176
|
-
# @return [Proc]
|
177
|
-
#
|
178
|
-
# @api public
|
179
|
-
def to_proc
|
180
|
-
proc { |value| self.(value) }
|
181
|
-
end
|
182
94
|
end
|
183
95
|
end
|
184
96
|
end
|
data/lib/dry/types/version.rb
CHANGED
data/lib/dry/types.rb
CHANGED
@@ -8,13 +8,16 @@ require "zeitwerk"
|
|
8
8
|
require "concurrent/map"
|
9
9
|
|
10
10
|
require "dry/core"
|
11
|
-
require "dry/container"
|
12
11
|
require "dry/logic"
|
13
12
|
|
14
13
|
require "dry/types/constraints"
|
15
14
|
require "dry/types/errors"
|
16
15
|
require "dry/types/version"
|
17
16
|
|
17
|
+
# This must be required explicitly as it may conflict with dry-inflector
|
18
|
+
require "dry/types/inflector"
|
19
|
+
require "dry/types/module"
|
20
|
+
|
18
21
|
module Dry
|
19
22
|
# Main library namespace
|
20
23
|
#
|
@@ -37,6 +40,7 @@ module Dry
|
|
37
40
|
loader.ignore(
|
38
41
|
"#{root}/dry-types.rb",
|
39
42
|
"#{root}/dry/types/extensions",
|
43
|
+
"#{root}/dry/types/printer",
|
40
44
|
"#{root}/dry/types/spec/types.rb",
|
41
45
|
"#{root}/dry/types/{#{%w[
|
42
46
|
compat
|
@@ -44,6 +48,8 @@ module Dry
|
|
44
48
|
core
|
45
49
|
errors
|
46
50
|
extensions
|
51
|
+
inflector
|
52
|
+
module
|
47
53
|
json
|
48
54
|
params
|
49
55
|
printer
|
@@ -141,7 +147,7 @@ module Dry
|
|
141
147
|
#
|
142
148
|
# @return [String]
|
143
149
|
def self.identifier(klass)
|
144
|
-
Inflector.underscore(klass).tr("/", ".")
|
150
|
+
Types::Inflector.underscore(klass).tr("/", ".")
|
145
151
|
end
|
146
152
|
|
147
153
|
# Cached type map
|
@@ -155,7 +161,7 @@ module Dry
|
|
155
161
|
|
156
162
|
# @api private
|
157
163
|
def self.const_missing(const)
|
158
|
-
underscored = Inflector.underscore(const)
|
164
|
+
underscored = Types::Inflector.underscore(const)
|
159
165
|
|
160
166
|
if container.keys.any? { |key| key.split(".")[0] == underscored }
|
161
167
|
raise ::NameError,
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-types
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.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: 2022-
|
11
|
+
date: 2022-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -24,80 +24,66 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: dry-container
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0.3'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0.3'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: dry-core
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
31
|
- - "~>"
|
46
32
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0
|
48
|
-
- - "
|
33
|
+
version: '1.0'
|
34
|
+
- - "<"
|
49
35
|
- !ruby/object:Gem::Version
|
50
|
-
version: '
|
36
|
+
version: '2'
|
51
37
|
type: :runtime
|
52
38
|
prerelease: false
|
53
39
|
version_requirements: !ruby/object:Gem::Requirement
|
54
40
|
requirements:
|
55
41
|
- - "~>"
|
56
42
|
- !ruby/object:Gem::Version
|
57
|
-
version: '0
|
58
|
-
- - "
|
43
|
+
version: '1.0'
|
44
|
+
- - "<"
|
59
45
|
- !ruby/object:Gem::Version
|
60
|
-
version: '
|
46
|
+
version: '2'
|
61
47
|
- !ruby/object:Gem::Dependency
|
62
48
|
name: dry-inflector
|
63
49
|
requirement: !ruby/object:Gem::Requirement
|
64
50
|
requirements:
|
65
51
|
- - "~>"
|
66
52
|
- !ruby/object:Gem::Version
|
67
|
-
version: '0
|
68
|
-
- - "
|
53
|
+
version: '1.0'
|
54
|
+
- - "<"
|
69
55
|
- !ruby/object:Gem::Version
|
70
|
-
version:
|
56
|
+
version: '2'
|
71
57
|
type: :runtime
|
72
58
|
prerelease: false
|
73
59
|
version_requirements: !ruby/object:Gem::Requirement
|
74
60
|
requirements:
|
75
61
|
- - "~>"
|
76
62
|
- !ruby/object:Gem::Version
|
77
|
-
version: '0
|
78
|
-
- - "
|
63
|
+
version: '1.0'
|
64
|
+
- - "<"
|
79
65
|
- !ruby/object:Gem::Version
|
80
|
-
version:
|
66
|
+
version: '2'
|
81
67
|
- !ruby/object:Gem::Dependency
|
82
68
|
name: dry-logic
|
83
69
|
requirement: !ruby/object:Gem::Requirement
|
84
70
|
requirements:
|
85
|
-
- - "~>"
|
86
|
-
- !ruby/object:Gem::Version
|
87
|
-
version: '1.3'
|
88
71
|
- - ">="
|
89
72
|
- !ruby/object:Gem::Version
|
90
|
-
version: '1.
|
73
|
+
version: '1.4'
|
74
|
+
- - "<"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '2'
|
91
77
|
type: :runtime
|
92
78
|
prerelease: false
|
93
79
|
version_requirements: !ruby/object:Gem::Requirement
|
94
80
|
requirements:
|
95
|
-
- - "~>"
|
96
|
-
- !ruby/object:Gem::Version
|
97
|
-
version: '1.3'
|
98
81
|
- - ">="
|
99
82
|
- !ruby/object:Gem::Version
|
100
|
-
version: '1.
|
83
|
+
version: '1.4'
|
84
|
+
- - "<"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '2'
|
101
87
|
- !ruby/object:Gem::Dependency
|
102
88
|
name: zeitwerk
|
103
89
|
requirement: !ruby/object:Gem::Requirement
|
@@ -126,20 +112,6 @@ dependencies:
|
|
126
112
|
- - ">="
|
127
113
|
- !ruby/object:Gem::Version
|
128
114
|
version: '0'
|
129
|
-
- !ruby/object:Gem::Dependency
|
130
|
-
name: dry-monads
|
131
|
-
requirement: !ruby/object:Gem::Requirement
|
132
|
-
requirements:
|
133
|
-
- - "~>"
|
134
|
-
- !ruby/object:Gem::Version
|
135
|
-
version: '1.0'
|
136
|
-
type: :development
|
137
|
-
prerelease: false
|
138
|
-
version_requirements: !ruby/object:Gem::Requirement
|
139
|
-
requirements:
|
140
|
-
- - "~>"
|
141
|
-
- !ruby/object:Gem::Version
|
142
|
-
version: '1.0'
|
143
115
|
- !ruby/object:Gem::Dependency
|
144
116
|
name: rake
|
145
117
|
requirement: !ruby/object:Gem::Requirement
|
@@ -207,6 +179,7 @@ files:
|
|
207
179
|
- lib/dry/types/coercions/params.rb
|
208
180
|
- lib/dry/types/compat.rb
|
209
181
|
- lib/dry/types/compiler.rb
|
182
|
+
- lib/dry/types/composition.rb
|
210
183
|
- lib/dry/types/constrained.rb
|
211
184
|
- lib/dry/types/constrained/coercible.rb
|
212
185
|
- lib/dry/types/constraints.rb
|
@@ -225,7 +198,9 @@ files:
|
|
225
198
|
- lib/dry/types/fn_container.rb
|
226
199
|
- lib/dry/types/hash.rb
|
227
200
|
- lib/dry/types/hash/constructor.rb
|
201
|
+
- lib/dry/types/implication.rb
|
228
202
|
- lib/dry/types/inflector.rb
|
203
|
+
- lib/dry/types/intersection.rb
|
229
204
|
- lib/dry/types/json.rb
|
230
205
|
- lib/dry/types/lax.rb
|
231
206
|
- lib/dry/types/map.rb
|
@@ -239,6 +214,7 @@ files:
|
|
239
214
|
- lib/dry/types/primitive_inferrer.rb
|
240
215
|
- lib/dry/types/printable.rb
|
241
216
|
- lib/dry/types/printer.rb
|
217
|
+
- lib/dry/types/printer/composition.rb
|
242
218
|
- lib/dry/types/result.rb
|
243
219
|
- lib/dry/types/schema.rb
|
244
220
|
- lib/dry/types/schema/key.rb
|