dry-types 1.2.2 → 1.5.1
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 +405 -225
- data/LICENSE +1 -1
- data/README.md +14 -12
- data/dry-types.gemspec +26 -31
- data/lib/dry-types.rb +1 -1
- data/lib/dry/types.rb +55 -40
- data/lib/dry/types/any.rb +2 -2
- data/lib/dry/types/array.rb +2 -2
- data/lib/dry/types/array/constructor.rb +1 -1
- data/lib/dry/types/array/member.rb +1 -1
- data/lib/dry/types/builder.rb +70 -18
- data/lib/dry/types/builder_methods.rb +1 -2
- data/lib/dry/types/coercions.rb +0 -17
- data/lib/dry/types/coercions/json.rb +22 -5
- data/lib/dry/types/coercions/params.rb +20 -3
- data/lib/dry/types/compiler.rb +10 -10
- data/lib/dry/types/constrained.rb +6 -9
- data/lib/dry/types/constraints.rb +3 -3
- data/lib/dry/types/constructor.rb +40 -6
- data/lib/dry/types/constructor/function.rb +48 -32
- data/lib/dry/types/constructor/wrapper.rb +94 -0
- data/lib/dry/types/container.rb +1 -1
- data/lib/dry/types/core.rb +15 -13
- data/lib/dry/types/decorator.rb +2 -9
- data/lib/dry/types/default.rb +14 -1
- data/lib/dry/types/enum.rb +4 -3
- data/lib/dry/types/errors.rb +1 -1
- data/lib/dry/types/extensions.rb +2 -2
- data/lib/dry/types/extensions/maybe.rb +18 -17
- data/lib/dry/types/extensions/monads.rb +1 -1
- data/lib/dry/types/fn_container.rb +1 -1
- data/lib/dry/types/hash.rb +9 -15
- data/lib/dry/types/hash/constructor.rb +1 -1
- data/lib/dry/types/inflector.rb +1 -1
- data/lib/dry/types/json.rb +15 -15
- data/lib/dry/types/lax.rb +3 -6
- data/lib/dry/types/map.rb +2 -2
- data/lib/dry/types/meta.rb +3 -3
- data/lib/dry/types/module.rb +6 -6
- data/lib/dry/types/nominal.rb +11 -11
- data/lib/dry/types/params.rb +31 -28
- data/lib/dry/types/predicate_inferrer.rb +52 -11
- data/lib/dry/types/predicate_registry.rb +1 -1
- data/lib/dry/types/primitive_inferrer.rb +1 -1
- data/lib/dry/types/printer.rb +25 -25
- data/lib/dry/types/result.rb +3 -3
- data/lib/dry/types/schema.rb +26 -13
- data/lib/dry/types/schema/key.rb +15 -6
- data/lib/dry/types/spec/types.rb +65 -42
- data/lib/dry/types/sum.rb +6 -5
- data/lib/dry/types/type.rb +1 -1
- data/lib/dry/types/version.rb +1 -1
- metadata +27 -78
- 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
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
module Types
|
5
|
+
# @api public
|
6
|
+
class Constructor < Nominal
|
7
|
+
module Wrapper
|
8
|
+
# @return [Object]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
def call_safe(input, &block)
|
12
|
+
fn.(input, type, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Object]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
def call_unsafe(input)
|
19
|
+
fn.(input, type)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param [Object] input
|
23
|
+
# @param [#call,nil] block
|
24
|
+
#
|
25
|
+
# @return [Logic::Result, Types::Result]
|
26
|
+
# @return [Object] if block given and try fails
|
27
|
+
#
|
28
|
+
# @api public
|
29
|
+
def try(input, &block)
|
30
|
+
value = fn.(input, type)
|
31
|
+
rescue CoercionError => e
|
32
|
+
failure = failure(input, e)
|
33
|
+
block_given? ? yield(failure) : failure
|
34
|
+
else
|
35
|
+
type.try(value, &block)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Define a constructor for the type
|
39
|
+
#
|
40
|
+
# @param [#call,nil] constructor
|
41
|
+
# @param [Hash] options
|
42
|
+
# @param [#call,nil] block
|
43
|
+
#
|
44
|
+
# @return [Constructor]
|
45
|
+
#
|
46
|
+
# @api public
|
47
|
+
define_method(:constructor, Builder.instance_method(:constructor))
|
48
|
+
alias_method :append, :constructor
|
49
|
+
alias_method :>>, :constructor
|
50
|
+
|
51
|
+
# Build a new constructor by prepending a block to the coercion function
|
52
|
+
#
|
53
|
+
# @param [#call, nil] new_fn
|
54
|
+
# @param [Hash] options
|
55
|
+
# @param [#call, nil] block
|
56
|
+
#
|
57
|
+
# @return [Constructor]
|
58
|
+
#
|
59
|
+
# @api public
|
60
|
+
def prepend(new_fn = nil, **options, &block)
|
61
|
+
prep_fn = Function[new_fn || block]
|
62
|
+
|
63
|
+
decorated =
|
64
|
+
if prep_fn.wrapper?
|
65
|
+
type.constructor(prep_fn, **options)
|
66
|
+
else
|
67
|
+
type.prepend(prep_fn, **options)
|
68
|
+
end
|
69
|
+
|
70
|
+
__new__(decorated)
|
71
|
+
end
|
72
|
+
alias_method :<<, :prepend
|
73
|
+
|
74
|
+
# @return [Constructor]
|
75
|
+
#
|
76
|
+
# @api public
|
77
|
+
def lax
|
78
|
+
# return self back because wrapping function
|
79
|
+
# can handle failed type check
|
80
|
+
self
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
# Replace underlying type
|
86
|
+
#
|
87
|
+
# @api private
|
88
|
+
def __new__(type)
|
89
|
+
self.class.new(type, *@__args__.drop(1), **@options)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/dry/types/container.rb
CHANGED
data/lib/dry/types/core.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/types/any"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Types
|
@@ -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
|
@@ -81,17 +83,17 @@ module Dry
|
|
81
83
|
end
|
82
84
|
|
83
85
|
# Register `:bool` since it's common and not a built-in Ruby type :(
|
84
|
-
register(
|
85
|
-
bool = self[
|
86
|
-
register(
|
87
|
-
register(
|
88
|
-
|
89
|
-
register(
|
90
|
-
register(
|
91
|
-
register(
|
86
|
+
register("nominal.bool", self["nominal.true"] | self["nominal.false"])
|
87
|
+
bool = self["strict.true"] | self["strict.false"]
|
88
|
+
register("strict.bool", bool)
|
89
|
+
register("bool", bool)
|
90
|
+
|
91
|
+
register("any", Any)
|
92
|
+
register("nominal.any", Any)
|
93
|
+
register("strict.any", Any)
|
92
94
|
end
|
93
95
|
end
|
94
96
|
|
95
|
-
require
|
96
|
-
require
|
97
|
-
require
|
97
|
+
require "dry/types/coercions"
|
98
|
+
require "dry/types/params"
|
99
|
+
require "dry/types/json"
|
data/lib/dry/types/decorator.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/types/options"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Types
|
@@ -44,13 +44,6 @@ module Dry
|
|
44
44
|
type.constrained?
|
45
45
|
end
|
46
46
|
|
47
|
-
# @return [Sum]
|
48
|
-
#
|
49
|
-
# @api public
|
50
|
-
def optional
|
51
|
-
Types['strict.nil'] | self
|
52
|
-
end
|
53
|
-
|
54
47
|
# @param [Symbol] meth
|
55
48
|
# @param [Boolean] include_private
|
56
49
|
#
|
@@ -107,7 +100,7 @@ module Dry
|
|
107
100
|
#
|
108
101
|
# @api private
|
109
102
|
def __new__(type)
|
110
|
-
self.class.new(type, *@__args__
|
103
|
+
self.class.new(type, *@__args__.drop(1), **@options)
|
111
104
|
end
|
112
105
|
end
|
113
106
|
end
|
data/lib/dry/types/default.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/core/equalizer"
|
4
|
+
require "dry/types/decorator"
|
4
5
|
|
5
6
|
module Dry
|
6
7
|
module Types
|
@@ -17,6 +18,11 @@ module Dry
|
|
17
18
|
def evaluate
|
18
19
|
value.call(type)
|
19
20
|
end
|
21
|
+
|
22
|
+
# @return [true]
|
23
|
+
def callable?
|
24
|
+
true
|
25
|
+
end
|
20
26
|
end
|
21
27
|
|
22
28
|
include Type
|
@@ -111,6 +117,13 @@ module Dry
|
|
111
117
|
Undefined.default(type.call_safe(input, &block)) { evaluate }
|
112
118
|
end
|
113
119
|
end
|
120
|
+
|
121
|
+
# @return [false]
|
122
|
+
#
|
123
|
+
# @api private
|
124
|
+
def callable?
|
125
|
+
false
|
126
|
+
end
|
114
127
|
end
|
115
128
|
end
|
116
129
|
end
|
data/lib/dry/types/enum.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/core/equalizer"
|
4
|
+
require "dry/types/decorator"
|
4
5
|
|
5
6
|
module Dry
|
6
7
|
module Types
|
@@ -58,8 +59,8 @@ module Dry
|
|
58
59
|
|
59
60
|
# @api private
|
60
61
|
def default(*)
|
61
|
-
raise
|
62
|
-
|
62
|
+
raise ".enum(*values).default(value) is not supported. Call "\
|
63
|
+
".default(value).enum(*values) instead"
|
63
64
|
end
|
64
65
|
|
65
66
|
# Check whether a value is in the enum
|
data/lib/dry/types/errors.rb
CHANGED
data/lib/dry/types/extensions.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
Dry::Types.register_extension(:maybe) do
|
4
|
-
require
|
4
|
+
require "dry/types/extensions/maybe"
|
5
5
|
end
|
6
6
|
|
7
7
|
Dry::Types.register_extension(:monads) do
|
8
|
-
require
|
8
|
+
require "dry/types/extensions/monads"
|
9
9
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/core/equalizer"
|
4
|
+
require "dry/monads/maybe"
|
5
|
+
require "dry/types/decorator"
|
5
6
|
|
6
7
|
module Dry
|
7
8
|
module Types
|
@@ -10,11 +11,11 @@ module Dry
|
|
10
11
|
# @api public
|
11
12
|
class Maybe
|
12
13
|
include Type
|
13
|
-
include Dry::Equalizer(:type, :options, inspect: false, immutable: true)
|
14
|
+
include ::Dry::Equalizer(:type, :options, inspect: false, immutable: true)
|
14
15
|
include Decorator
|
15
16
|
include Builder
|
16
17
|
include Printable
|
17
|
-
include Dry::Monads::Maybe::Mixin
|
18
|
+
include ::Dry::Monads::Maybe::Mixin
|
18
19
|
|
19
20
|
# @param [Dry::Monads::Maybe, Object] input
|
20
21
|
#
|
@@ -23,7 +24,7 @@ module Dry
|
|
23
24
|
# @api private
|
24
25
|
def call_unsafe(input = Undefined)
|
25
26
|
case input
|
26
|
-
when Dry::Monads::Maybe
|
27
|
+
when ::Dry::Monads::Maybe
|
27
28
|
input
|
28
29
|
when Undefined
|
29
30
|
None()
|
@@ -37,14 +38,14 @@ module Dry
|
|
37
38
|
# @return [Dry::Monads::Maybe]
|
38
39
|
#
|
39
40
|
# @api private
|
40
|
-
def call_safe(input = Undefined
|
41
|
+
def call_safe(input = Undefined)
|
41
42
|
case input
|
42
|
-
when Dry::Monads::Maybe
|
43
|
+
when ::Dry::Monads::Maybe
|
43
44
|
input
|
44
45
|
when Undefined
|
45
46
|
None()
|
46
47
|
else
|
47
|
-
Maybe(type.call_safe(input
|
48
|
+
Maybe(type.call_safe(input) { |output = input| return yield(output) })
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
@@ -54,13 +55,13 @@ module Dry
|
|
54
55
|
#
|
55
56
|
# @api public
|
56
57
|
def try(input = Undefined)
|
57
|
-
|
58
|
-
None()
|
59
|
-
else
|
60
|
-
Maybe(type[input])
|
61
|
-
end
|
58
|
+
result = type.try(input)
|
62
59
|
|
63
|
-
|
60
|
+
if result.success?
|
61
|
+
Result::Success.new(Maybe(result.input))
|
62
|
+
else
|
63
|
+
result
|
64
|
+
end
|
64
65
|
end
|
65
66
|
|
66
67
|
# @return [true]
|
@@ -79,7 +80,7 @@ module Dry
|
|
79
80
|
# @api public
|
80
81
|
def default(value)
|
81
82
|
if value.nil?
|
82
|
-
raise ArgumentError,
|
83
|
+
raise ArgumentError, "nil cannot be used as a default of a maybe type"
|
83
84
|
else
|
84
85
|
super
|
85
86
|
end
|
@@ -93,7 +94,7 @@ module Dry
|
|
93
94
|
#
|
94
95
|
# @api public
|
95
96
|
def maybe
|
96
|
-
Maybe.new(Types[
|
97
|
+
Maybe.new(Types["nil"] | self)
|
97
98
|
end
|
98
99
|
end
|
99
100
|
|
@@ -119,7 +120,7 @@ module Dry
|
|
119
120
|
|
120
121
|
# Register non-coercible maybe types
|
121
122
|
NON_NIL.each_key do |name|
|
122
|
-
register("maybe.strict.#{name}", self[
|
123
|
+
register("maybe.strict.#{name}", self[name.to_s].maybe)
|
123
124
|
end
|
124
125
|
|
125
126
|
# Register coercible maybe types
|
data/lib/dry/types/hash.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/types/hash/constructor"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Types
|
@@ -8,7 +8,7 @@ module Dry
|
|
8
8
|
#
|
9
9
|
# @api public
|
10
10
|
class Hash < Nominal
|
11
|
-
NOT_REQUIRED = {
|
11
|
+
NOT_REQUIRED = {required: false}.freeze
|
12
12
|
|
13
13
|
# @overload schema(type_map, meta = EMPTY_HASH)
|
14
14
|
# @param [{Symbol => Dry::Types::Nominal}] type_map
|
@@ -50,8 +50,8 @@ module Dry
|
|
50
50
|
|
51
51
|
# @api private
|
52
52
|
def weak(*)
|
53
|
-
raise
|
54
|
-
|
53
|
+
raise "Support for old hash schemas was removed, please refer to the CHANGELOG "\
|
54
|
+
"on how to proceed with the new API https://github.com/dry-rb/dry-types/blob/master/CHANGELOG.md"
|
55
55
|
end
|
56
56
|
alias_method :permissive, :weak
|
57
57
|
alias_method :strict, :weak
|
@@ -69,7 +69,7 @@ module Dry
|
|
69
69
|
def with_type_transform(proc = nil, &block)
|
70
70
|
fn = proc || block
|
71
71
|
|
72
|
-
raise ArgumentError,
|
72
|
+
raise ArgumentError, "a block or callable argument is required" if fn.nil?
|
73
73
|
|
74
74
|
handle = Dry::Types::FnContainer.register(fn)
|
75
75
|
with(type_transform_fn: handle)
|
@@ -95,13 +95,7 @@ module Dry
|
|
95
95
|
#
|
96
96
|
# @api public
|
97
97
|
def to_ast(meta: true)
|
98
|
-
|
99
|
-
options.slice(:type_transform_fn)
|
100
|
-
else
|
101
|
-
options.select { |k, _| k == :type_transform_fn }
|
102
|
-
end
|
103
|
-
|
104
|
-
[:hash, [opts, meta ? self.meta : EMPTY_HASH]]
|
98
|
+
[:hash, [options.slice(:type_transform_fn), meta ? self.meta : EMPTY_HASH]]
|
105
99
|
end
|
106
100
|
|
107
101
|
private
|
@@ -129,7 +123,7 @@ module Dry
|
|
129
123
|
|
130
124
|
# @api private
|
131
125
|
def key_name(key)
|
132
|
-
if key.to_s.end_with?(
|
126
|
+
if key.to_s.end_with?("?")
|
133
127
|
[key.to_s.chop.to_sym, NOT_REQUIRED]
|
134
128
|
else
|
135
129
|
[key, EMPTY_HASH]
|
@@ -139,5 +133,5 @@ module Dry
|
|
139
133
|
end
|
140
134
|
end
|
141
135
|
|
142
|
-
require
|
143
|
-
require
|
136
|
+
require "dry/types/schema/key"
|
137
|
+
require "dry/types/schema"
|