dry-types 1.2.2 → 1.3.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 +306 -225
- data/LICENSE +1 -1
- data/README.md +14 -12
- data/dry-types.gemspec +27 -31
- data/lib/dry/types.rb +0 -9
- data/lib/dry/types/builder.rb +4 -0
- data/lib/dry/types/constructor/function.rb +17 -31
- data/lib/dry/types/core.rb +3 -1
- data/lib/dry/types/decorator.rb +0 -7
- data/lib/dry/types/extensions/maybe.rb +14 -14
- data/lib/dry/types/lax.rb +1 -4
- data/lib/dry/types/meta.rb +2 -2
- data/lib/dry/types/params.rb +1 -0
- data/lib/dry/types/result.rb +2 -2
- data/lib/dry/types/schema.rb +23 -2
- data/lib/dry/types/schema/key.rb +11 -2
- data/lib/dry/types/spec/types.rb +11 -0
- data/lib/dry/types/sum.rb +2 -2
- data/lib/dry/types/version.rb +1 -1
- metadata +21 -59
- data/.codeclimate.yml +0 -12
- data/.github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md +0 -10
- data/.github/ISSUE_TEMPLATE/---bug-report.md +0 -30
- data/.github/ISSUE_TEMPLATE/---feature-request.md +0 -18
- data/.github/workflows/custom_ci.yml +0 -76
- data/.github/workflows/docsite.yml +0 -34
- data/.github/workflows/sync_configs.yml +0 -34
- data/.gitignore +0 -11
- data/.rspec +0 -4
- data/.rubocop.yml +0 -92
- data/.yardopts +0 -9
- data/CODE_OF_CONDUCT.md +0 -13
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -34
- data/Rakefile +0 -22
- data/benchmarks/hash_schemas.rb +0 -55
- data/benchmarks/lax_schema.rb +0 -15
- data/benchmarks/profile_invalid_input.rb +0 -15
- data/benchmarks/profile_lax_schema_valid.rb +0 -16
- data/benchmarks/profile_valid_input.rb +0 -15
- data/benchmarks/schema_valid_vs_invalid.rb +0 -21
- data/benchmarks/setup.rb +0 -17
- data/docsite/source/array-with-member.html.md +0 -13
- data/docsite/source/built-in-types.html.md +0 -116
- data/docsite/source/constraints.html.md +0 -31
- data/docsite/source/custom-types.html.md +0 -93
- data/docsite/source/default-values.html.md +0 -91
- data/docsite/source/enum.html.md +0 -69
- data/docsite/source/extensions.html.md +0 -15
- data/docsite/source/extensions/maybe.html.md +0 -57
- data/docsite/source/extensions/monads.html.md +0 -61
- data/docsite/source/getting-started.html.md +0 -57
- data/docsite/source/hash-schemas.html.md +0 -169
- data/docsite/source/index.html.md +0 -156
- data/docsite/source/map.html.md +0 -17
- data/docsite/source/optional-values.html.md +0 -35
- data/docsite/source/sum.html.md +0 -21
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,27 +1,29 @@
|
|
1
1
|
[gem]: https://rubygems.org/gems/dry-types
|
2
|
-
[
|
3
|
-
[
|
4
|
-
[inchpages]: http://inch-ci.org/github/dry-rb/dry-types
|
2
|
+
[actions]: https://github.com/dry-rb/dry-types/actions
|
3
|
+
[codacy]: https://www.codacy.com/gh/dry-rb/dry-types
|
5
4
|
[chat]: https://dry-rb.zulipchat.com
|
5
|
+
[inchpages]: http://inch-ci.org/github/dry-rb/dry-types
|
6
6
|
|
7
7
|
# dry-types [][chat]
|
8
8
|
|
9
9
|
[][gem]
|
10
|
-
[][actions]
|
11
|
+
[][codacy]
|
12
|
+
[][codacy]
|
13
13
|
[][inchpages]
|
14
14
|
|
15
15
|
## Links
|
16
16
|
|
17
|
-
|
17
|
+
* [User documentation](http://dry-rb.org/gems/dry-types)
|
18
|
+
* [API documentation](http://rubydoc.info/gems/dry-types)
|
18
19
|
|
19
|
-
##
|
20
|
+
## Supported Ruby versions
|
20
21
|
|
21
|
-
|
22
|
+
This library officially supports the following Ruby versions:
|
22
23
|
|
23
|
-
|
24
|
+
* MRI >= `2.4`
|
25
|
+
* jruby >= `9.2`
|
24
26
|
|
25
|
-
##
|
27
|
+
## License
|
26
28
|
|
27
|
-
|
29
|
+
See `LICENSE` file.
|
data/dry-types.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# this file is managed by dry-rb/devtools project
|
2
3
|
|
3
4
|
lib = File.expand_path('lib', __dir__)
|
4
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
@@ -6,42 +7,37 @@ require 'dry/types/version'
|
|
6
7
|
|
7
8
|
Gem::Specification.new do |spec|
|
8
9
|
spec.name = 'dry-types'
|
9
|
-
spec.
|
10
|
-
spec.
|
11
|
-
spec.email = ['piotr.solnica@gmail.com']
|
10
|
+
spec.authors = ["Piotr Solnica"]
|
11
|
+
spec.email = ["piotr.solnica@gmail.com"]
|
12
12
|
spec.license = 'MIT'
|
13
|
+
spec.version = Dry::Types::VERSION.dup
|
13
14
|
|
14
|
-
spec.summary =
|
15
|
+
spec.summary = "Type system for Ruby supporting coercions, constraints and complex types like structs, value objects, enums etc"
|
15
16
|
spec.description = spec.summary
|
16
|
-
spec.homepage = 'https://
|
17
|
+
spec.homepage = 'https://dry-rb.org/gems/dry-types'
|
18
|
+
spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-types.gemspec", "lib/**/*"]
|
19
|
+
spec.bindir = 'bin'
|
20
|
+
spec.executables = []
|
21
|
+
spec.require_paths = ['lib']
|
17
22
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
spec.metadata['changelog_uri'] = 'https://github.com/dry-rb/dry-types/blob/master/CHANGELOG.md'
|
23
|
-
spec.metadata['source_code_uri'] = 'https://github.com/dry-rb/dry-types'
|
24
|
-
spec.metadata['bug_tracker_uri'] = 'https://github.com/dry-rb/dry-types/issues'
|
25
|
-
else
|
26
|
-
raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
|
27
|
-
end
|
23
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
24
|
+
spec.metadata['changelog_uri'] = 'https://github.com/dry-rb/dry-types/blob/master/CHANGELOG.md'
|
25
|
+
spec.metadata['source_code_uri'] = 'https://github.com/dry-rb/dry-types'
|
26
|
+
spec.metadata['bug_tracker_uri'] = 'https://github.com/dry-rb/dry-types/issues'
|
28
27
|
|
29
|
-
spec.
|
30
|
-
spec.bindir = 'exe'
|
31
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
32
|
-
spec.require_paths = ['lib']
|
33
|
-
spec.required_ruby_version = '>= 2.4.0'
|
28
|
+
spec.required_ruby_version = ">= 2.4.0"
|
34
29
|
|
35
|
-
|
36
|
-
spec.add_runtime_dependency
|
37
|
-
spec.add_runtime_dependency
|
38
|
-
spec.add_runtime_dependency
|
39
|
-
spec.add_runtime_dependency
|
40
|
-
spec.add_runtime_dependency
|
30
|
+
# to update dependencies edit project.yml
|
31
|
+
spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
|
32
|
+
spec.add_runtime_dependency "dry-container", "~> 0.3"
|
33
|
+
spec.add_runtime_dependency "dry-core", "~> 0.4", ">= 0.4.4"
|
34
|
+
spec.add_runtime_dependency "dry-equalizer", "~> 0.3"
|
35
|
+
spec.add_runtime_dependency "dry-inflector", "~> 0.1", ">= 0.1.2"
|
36
|
+
spec.add_runtime_dependency "dry-logic", "~> 1.0", ">= 1.0.2"
|
41
37
|
|
42
|
-
spec.add_development_dependency
|
43
|
-
spec.add_development_dependency
|
44
|
-
spec.add_development_dependency
|
45
|
-
spec.add_development_dependency
|
46
|
-
spec.add_development_dependency
|
38
|
+
spec.add_development_dependency "bundler"
|
39
|
+
spec.add_development_dependency "dry-monads", "~> 1.0"
|
40
|
+
spec.add_development_dependency "rake"
|
41
|
+
spec.add_development_dependency "rspec"
|
42
|
+
spec.add_development_dependency "yard"
|
47
43
|
end
|
data/lib/dry/types.rb
CHANGED
@@ -133,15 +133,6 @@ module Dry
|
|
133
133
|
@type_map ||= Concurrent::Map.new
|
134
134
|
end
|
135
135
|
|
136
|
-
# List of type keys defined in {Dry::Types.container}
|
137
|
-
#
|
138
|
-
# @return [String]
|
139
|
-
#
|
140
|
-
# @api private
|
141
|
-
def self.type_keys
|
142
|
-
container.keys
|
143
|
-
end
|
144
|
-
|
145
136
|
# @api private
|
146
137
|
def self.const_missing(const)
|
147
138
|
underscored = Inflector.underscore(const)
|
data/lib/dry/types/builder.rb
CHANGED
@@ -129,6 +129,10 @@ module Dry
|
|
129
129
|
def constructor(constructor = nil, **options, &block)
|
130
130
|
constructor_type.new(with(**options), fn: constructor || block)
|
131
131
|
end
|
132
|
+
alias_method :append, :constructor
|
133
|
+
alias_method :prepend, :constructor
|
134
|
+
alias_method :>>, :constructor
|
135
|
+
alias_method :<<, :constructor
|
132
136
|
end
|
133
137
|
end
|
134
138
|
end
|
@@ -15,7 +15,7 @@ module Dry
|
|
15
15
|
class Safe < Function
|
16
16
|
def call(input, &block)
|
17
17
|
@fn.(input, &block)
|
18
|
-
rescue NoMethodError, TypeError, ArgumentError => e
|
18
|
+
rescue ::NoMethodError, ::TypeError, ::ArgumentError => e
|
19
19
|
CoercionError.handle(e, &block)
|
20
20
|
end
|
21
21
|
end
|
@@ -30,7 +30,7 @@ module Dry
|
|
30
30
|
#
|
31
31
|
# @return [Function]
|
32
32
|
def self.call_class(method, public, safe)
|
33
|
-
@cache.fetch_or_store([method, public, safe]
|
33
|
+
@cache.fetch_or_store([method, public, safe]) do
|
34
34
|
if public
|
35
35
|
::Class.new(PublicCall) do
|
36
36
|
include PublicCall.call_interface(method, safe)
|
@@ -53,7 +53,7 @@ module Dry
|
|
53
53
|
#
|
54
54
|
# @return [::Module]
|
55
55
|
def self.call_interface(method, safe)
|
56
|
-
@interfaces.fetch_or_store([method, safe]
|
56
|
+
@interfaces.fetch_or_store([method, safe]) do
|
57
57
|
::Module.new do
|
58
58
|
if safe
|
59
59
|
module_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
@@ -65,7 +65,7 @@ module Dry
|
|
65
65
|
module_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
66
66
|
def call(input, &block)
|
67
67
|
@target.#{method}(input)
|
68
|
-
rescue NoMethodError, TypeError, ArgumentError => error
|
68
|
+
rescue ::NoMethodError, ::TypeError, ::ArgumentError => error
|
69
69
|
CoercionError.handle(error, &block)
|
70
70
|
end
|
71
71
|
RUBY
|
@@ -90,7 +90,7 @@ module Dry
|
|
90
90
|
class PrivateSafeCall < PrivateCall
|
91
91
|
def call(input, &block)
|
92
92
|
@target.send(@name, input)
|
93
|
-
rescue NoMethodError, TypeError, ArgumentError => e
|
93
|
+
rescue ::NoMethodError, ::TypeError, ::ArgumentError => e
|
94
94
|
CoercionError.handle(e, &block)
|
95
95
|
end
|
96
96
|
end
|
@@ -121,7 +121,7 @@ module Dry
|
|
121
121
|
# @param [#call] fn
|
122
122
|
# @return [Function]
|
123
123
|
def self.[](fn)
|
124
|
-
raise ArgumentError, 'Missing constructor block' if fn.nil?
|
124
|
+
raise ::ArgumentError, 'Missing constructor block' if fn.nil?
|
125
125
|
|
126
126
|
if fn.is_a?(Function)
|
127
127
|
fn
|
@@ -146,7 +146,7 @@ module Dry
|
|
146
146
|
last_arg.equal?(:block)
|
147
147
|
end
|
148
148
|
|
149
|
-
include Dry::Equalizer(:fn, immutable: true)
|
149
|
+
include ::Dry::Equalizer(:fn, immutable: true)
|
150
150
|
|
151
151
|
attr_reader :fn
|
152
152
|
|
@@ -163,36 +163,22 @@ module Dry
|
|
163
163
|
# @return [Array]
|
164
164
|
def to_ast
|
165
165
|
if fn.is_a?(::Proc)
|
166
|
-
[:id,
|
166
|
+
[:id, FnContainer.register(fn)]
|
167
167
|
else
|
168
168
|
[:callable, fn]
|
169
169
|
end
|
170
170
|
end
|
171
171
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
end
|
178
|
-
|
179
|
-
# @return [Function]
|
180
|
-
def <<(other)
|
181
|
-
proc = other.is_a?(::Proc) ? other : other.fn
|
182
|
-
Function[@fn << proc]
|
183
|
-
end
|
184
|
-
else
|
185
|
-
# @return [Function]
|
186
|
-
def >>(other)
|
187
|
-
proc = other.is_a?(::Proc) ? other : other.fn
|
188
|
-
Function[-> x { proc[@fn[x]] }]
|
189
|
-
end
|
172
|
+
# @return [Function]
|
173
|
+
def >>(other)
|
174
|
+
f = Function[other]
|
175
|
+
Function[-> x, &b { f.(self.(x, &b), &b) }]
|
176
|
+
end
|
190
177
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
end
|
178
|
+
# @return [Function]
|
179
|
+
def <<(other)
|
180
|
+
f = Function[other]
|
181
|
+
Function[-> x, &b { self.(f.(x, &b), &b) }]
|
196
182
|
end
|
197
183
|
end
|
198
184
|
end
|
data/lib/dry/types/core.rb
CHANGED
@@ -72,7 +72,9 @@ module Dry
|
|
72
72
|
|
73
73
|
# Register optional strict {NON_NIL} types
|
74
74
|
NON_NIL.each_key do |name|
|
75
|
-
|
75
|
+
type = self[name.to_s].optional
|
76
|
+
register("optional.strict.#{name}", type)
|
77
|
+
register("optional.#{name}", type)
|
76
78
|
end
|
77
79
|
|
78
80
|
# Register optional {COERCIBLE} types
|
data/lib/dry/types/decorator.rb
CHANGED
@@ -10,11 +10,11 @@ module Dry
|
|
10
10
|
# @api public
|
11
11
|
class Maybe
|
12
12
|
include Type
|
13
|
-
include Dry::Equalizer(:type, :options, inspect: false, immutable: true)
|
13
|
+
include ::Dry::Equalizer(:type, :options, inspect: false, immutable: true)
|
14
14
|
include Decorator
|
15
15
|
include Builder
|
16
16
|
include Printable
|
17
|
-
include Dry::Monads::Maybe::Mixin
|
17
|
+
include ::Dry::Monads::Maybe::Mixin
|
18
18
|
|
19
19
|
# @param [Dry::Monads::Maybe, Object] input
|
20
20
|
#
|
@@ -23,7 +23,7 @@ module Dry
|
|
23
23
|
# @api private
|
24
24
|
def call_unsafe(input = Undefined)
|
25
25
|
case input
|
26
|
-
when Dry::Monads::Maybe
|
26
|
+
when ::Dry::Monads::Maybe
|
27
27
|
input
|
28
28
|
when Undefined
|
29
29
|
None()
|
@@ -37,14 +37,14 @@ module Dry
|
|
37
37
|
# @return [Dry::Monads::Maybe]
|
38
38
|
#
|
39
39
|
# @api private
|
40
|
-
def call_safe(input = Undefined
|
40
|
+
def call_safe(input = Undefined)
|
41
41
|
case input
|
42
|
-
when Dry::Monads::Maybe
|
42
|
+
when ::Dry::Monads::Maybe
|
43
43
|
input
|
44
44
|
when Undefined
|
45
45
|
None()
|
46
46
|
else
|
47
|
-
Maybe(type.call_safe(input
|
47
|
+
Maybe(type.call_safe(input) { |output = input| return yield(output) })
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -54,13 +54,13 @@ module Dry
|
|
54
54
|
#
|
55
55
|
# @api public
|
56
56
|
def try(input = Undefined)
|
57
|
-
|
58
|
-
None()
|
59
|
-
else
|
60
|
-
Maybe(type[input])
|
61
|
-
end
|
57
|
+
result = type.try(input)
|
62
58
|
|
63
|
-
|
59
|
+
if result.success?
|
60
|
+
Result::Success.new(Maybe(result.input))
|
61
|
+
else
|
62
|
+
result
|
63
|
+
end
|
64
64
|
end
|
65
65
|
|
66
66
|
# @return [true]
|
@@ -93,7 +93,7 @@ module Dry
|
|
93
93
|
#
|
94
94
|
# @api public
|
95
95
|
def maybe
|
96
|
-
Maybe.new(Types['
|
96
|
+
Maybe.new(Types['nil'] | self)
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
@@ -119,7 +119,7 @@ module Dry
|
|
119
119
|
|
120
120
|
# Register non-coercible maybe types
|
121
121
|
NON_NIL.each_key do |name|
|
122
|
-
register("maybe.strict.#{name}", self[
|
122
|
+
register("maybe.strict.#{name}", self[name.to_s].maybe)
|
123
123
|
end
|
124
124
|
|
125
125
|
# Register coercible maybe types
|
data/lib/dry/types/lax.rb
CHANGED
@@ -15,7 +15,7 @@ module Dry
|
|
15
15
|
include Printable
|
16
16
|
include Dry::Equalizer(:type, inspect: false, immutable: true)
|
17
17
|
|
18
|
-
undef :options, :constructor
|
18
|
+
undef :options, :constructor, :<<, :>>, :prepend, :append
|
19
19
|
|
20
20
|
# @param [Object] input
|
21
21
|
#
|
@@ -40,9 +40,6 @@ module Dry
|
|
40
40
|
# @api public
|
41
41
|
def try(input, &block)
|
42
42
|
type.try(input, &block)
|
43
|
-
rescue CoercionError => e
|
44
|
-
result = failure(input, e.message)
|
45
|
-
block ? yield(result) : result
|
46
43
|
end
|
47
44
|
|
48
45
|
# @see Nominal#to_ast
|
data/lib/dry/types/meta.rb
CHANGED
data/lib/dry/types/params.rb
CHANGED
data/lib/dry/types/result.rb
CHANGED
@@ -8,7 +8,7 @@ module Dry
|
|
8
8
|
#
|
9
9
|
# @api public
|
10
10
|
class Result
|
11
|
-
include Dry::Equalizer(:input,
|
11
|
+
include ::Dry::Equalizer(:input, immutable: true)
|
12
12
|
|
13
13
|
# @return [Object]
|
14
14
|
attr_reader :input
|
@@ -43,7 +43,7 @@ module Dry
|
|
43
43
|
#
|
44
44
|
# @api public
|
45
45
|
class Failure < Result
|
46
|
-
include Dry::Equalizer(:input, :error,
|
46
|
+
include ::Dry::Equalizer(:input, :error, immutable: true)
|
47
47
|
|
48
48
|
# @return [#to_s]
|
49
49
|
attr_reader :error
|
data/lib/dry/types/schema.rb
CHANGED
@@ -145,7 +145,7 @@ module Dry
|
|
145
145
|
#
|
146
146
|
# @api public
|
147
147
|
def to_ast(meta: true)
|
148
|
-
if RUBY_VERSION >=
|
148
|
+
if RUBY_VERSION >= '2.5'
|
149
149
|
opts = options.slice(:key_transform_fn, :type_transform_fn, :strict)
|
150
150
|
else
|
151
151
|
opts = options.select { |k, _|
|
@@ -179,7 +179,7 @@ module Dry
|
|
179
179
|
with(strict: strict)
|
180
180
|
end
|
181
181
|
|
182
|
-
#
|
182
|
+
# Inject a key transformation function
|
183
183
|
#
|
184
184
|
# @param [#call,nil] proc
|
185
185
|
# @param [#call,nil] block
|
@@ -284,6 +284,27 @@ module Dry
|
|
284
284
|
Lax.new(schema(keys.map(&:lax)))
|
285
285
|
end
|
286
286
|
|
287
|
+
# Merge given schema keys into current schema
|
288
|
+
#
|
289
|
+
# A new instance is returned.
|
290
|
+
#
|
291
|
+
# @param schema [Schema]
|
292
|
+
# @return [Schema]
|
293
|
+
#
|
294
|
+
# @api public
|
295
|
+
def merge(other)
|
296
|
+
schema(other.keys)
|
297
|
+
end
|
298
|
+
|
299
|
+
# Empty schema with the same options
|
300
|
+
#
|
301
|
+
# @return [Schema]
|
302
|
+
#
|
303
|
+
# @api public
|
304
|
+
def clear
|
305
|
+
with(keys: EMPTY_ARRAY)
|
306
|
+
end
|
307
|
+
|
287
308
|
private
|
288
309
|
|
289
310
|
# @param [Array<Dry::Types::Schema::Keys>] keys
|