dry-types 0.15.0 → 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 +547 -161
- data/LICENSE +17 -17
- data/README.md +15 -13
- data/dry-types.gemspec +27 -30
- data/lib/dry/types/any.rb +23 -12
- data/lib/dry/types/array/constructor.rb +32 -0
- data/lib/dry/types/array/member.rb +74 -15
- data/lib/dry/types/array.rb +18 -2
- data/lib/dry/types/builder.rb +118 -22
- data/lib/dry/types/builder_methods.rb +46 -16
- data/lib/dry/types/coercions/json.rb +43 -7
- data/lib/dry/types/coercions/params.rb +117 -32
- data/lib/dry/types/coercions.rb +76 -22
- data/lib/dry/types/compiler.rb +44 -21
- data/lib/dry/types/constrained/coercible.rb +36 -6
- data/lib/dry/types/constrained.rb +79 -31
- data/lib/dry/types/constraints.rb +18 -4
- data/lib/dry/types/constructor/function.rb +216 -0
- data/lib/dry/types/constructor/wrapper.rb +94 -0
- data/lib/dry/types/constructor.rb +110 -61
- data/lib/dry/types/container.rb +6 -1
- data/lib/dry/types/core.rb +34 -11
- data/lib/dry/types/decorator.rb +38 -17
- data/lib/dry/types/default.rb +61 -16
- data/lib/dry/types/enum.rb +36 -20
- data/lib/dry/types/errors.rb +74 -8
- data/lib/dry/types/extensions/maybe.rb +65 -17
- data/lib/dry/types/extensions/monads.rb +29 -0
- data/lib/dry/types/extensions.rb +7 -1
- data/lib/dry/types/fn_container.rb +6 -1
- data/lib/dry/types/hash/constructor.rb +17 -4
- data/lib/dry/types/hash.rb +32 -20
- data/lib/dry/types/inflector.rb +3 -1
- data/lib/dry/types/json.rb +18 -16
- data/lib/dry/types/lax.rb +75 -0
- data/lib/dry/types/map.rb +70 -32
- data/lib/dry/types/meta.rb +51 -0
- data/lib/dry/types/module.rb +16 -11
- data/lib/dry/types/nominal.rb +113 -22
- data/lib/dry/types/options.rb +12 -25
- data/lib/dry/types/params.rb +39 -25
- data/lib/dry/types/predicate_inferrer.rb +238 -0
- data/lib/dry/types/predicate_registry.rb +34 -0
- data/lib/dry/types/primitive_inferrer.rb +97 -0
- data/lib/dry/types/printable.rb +5 -1
- data/lib/dry/types/printer.rb +63 -57
- data/lib/dry/types/result.rb +29 -3
- data/lib/dry/types/schema/key.rb +62 -36
- data/lib/dry/types/schema.rb +201 -91
- data/lib/dry/types/spec/types.rb +99 -37
- data/lib/dry/types/sum.rb +75 -25
- data/lib/dry/types/type.rb +49 -0
- data/lib/dry/types/version.rb +3 -1
- data/lib/dry/types.rb +106 -48
- data/lib/dry-types.rb +3 -1
- metadata +55 -78
- data/.codeclimate.yml +0 -15
- data/.gitignore +0 -10
- data/.rspec +0 -2
- data/.rubocop.yml +0 -43
- data/.travis.yml +0 -28
- data/.yardopts +0 -5
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -23
- data/Rakefile +0 -20
- data/benchmarks/hash_schemas.rb +0 -51
- data/lib/dry/types/safe.rb +0 -61
- data/log/.gitkeep +0 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/core/deprecations"
|
4
|
+
require "dry/types/decorator"
|
5
|
+
|
6
|
+
module Dry
|
7
|
+
module Types
|
8
|
+
# Lax types rescue from type-related errors when constructors fail
|
9
|
+
#
|
10
|
+
# @api public
|
11
|
+
class Lax
|
12
|
+
include Type
|
13
|
+
include Decorator
|
14
|
+
include Builder
|
15
|
+
include Printable
|
16
|
+
include Dry::Equalizer(:type, inspect: false, immutable: true)
|
17
|
+
|
18
|
+
undef :options, :constructor, :<<, :>>, :prepend, :append
|
19
|
+
|
20
|
+
# @param [Object] input
|
21
|
+
#
|
22
|
+
# @return [Object]
|
23
|
+
#
|
24
|
+
# @api public
|
25
|
+
def call(input)
|
26
|
+
type.call_safe(input) { |output = input| output }
|
27
|
+
end
|
28
|
+
alias_method :[], :call
|
29
|
+
alias_method :call_safe, :call
|
30
|
+
alias_method :call_unsafe, :call
|
31
|
+
|
32
|
+
# @param [Object] input
|
33
|
+
# @param [#call,nil] block
|
34
|
+
#
|
35
|
+
# @yieldparam [Failure] failure
|
36
|
+
# @yieldreturn [Result]
|
37
|
+
#
|
38
|
+
# @return [Result,Logic::Result]
|
39
|
+
#
|
40
|
+
# @api public
|
41
|
+
def try(input, &block)
|
42
|
+
type.try(input, &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
# @see Nominal#to_ast
|
46
|
+
#
|
47
|
+
# @api public
|
48
|
+
def to_ast(meta: true)
|
49
|
+
[:lax, type.to_ast(meta: meta)]
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Lax]
|
53
|
+
#
|
54
|
+
# @api public
|
55
|
+
def lax
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# @param [Object, Dry::Types::Constructor] response
|
62
|
+
#
|
63
|
+
# @return [Boolean]
|
64
|
+
#
|
65
|
+
# @api private
|
66
|
+
def decorate?(response)
|
67
|
+
super || response.is_a?(type.constructor_type)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
extend ::Dry::Core::Deprecations[:'dry-types']
|
72
|
+
Safe = Lax
|
73
|
+
deprecate_constant(:Safe)
|
74
|
+
end
|
75
|
+
end
|
data/lib/dry/types/map.rb
CHANGED
@@ -1,96 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dry
|
2
4
|
module Types
|
5
|
+
# Homogeneous mapping. It describes a hash with unknown keys that match a certain type.
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# type = Dry::Types['hash'].map(
|
9
|
+
# Dry::Types['integer'].constrained(gteq: 1, lteq: 10),
|
10
|
+
# Dry::Types['string']
|
11
|
+
# )
|
12
|
+
#
|
13
|
+
# type.(1 => 'right')
|
14
|
+
# # => {1 => 'right'}
|
15
|
+
#
|
16
|
+
# type.('1' => 'wrong')
|
17
|
+
# # Dry::Types::MapError: "1" violates constraints (type?(Integer, "1") AND gteq?(1, "1") AND lteq?(10, "1") failed)
|
18
|
+
#
|
19
|
+
# type.(11 => 'wrong')
|
20
|
+
# # Dry::Types::MapError: 11 violates constraints (lteq?(10, 11) failed)
|
21
|
+
#
|
22
|
+
# @api public
|
3
23
|
class Map < Nominal
|
4
|
-
def initialize(_primitive, key_type: Types[
|
24
|
+
def initialize(_primitive, key_type: Types["any"], value_type: Types["any"], meta: EMPTY_HASH)
|
5
25
|
super(_primitive, key_type: key_type, value_type: value_type, meta: meta)
|
6
|
-
validate_options!
|
7
26
|
end
|
8
27
|
|
9
28
|
# @return [Type]
|
29
|
+
#
|
30
|
+
# @api public
|
10
31
|
def key_type
|
11
32
|
options[:key_type]
|
12
33
|
end
|
13
34
|
|
14
35
|
# @return [Type]
|
36
|
+
#
|
37
|
+
# @api public
|
15
38
|
def value_type
|
16
39
|
options[:value_type]
|
17
40
|
end
|
18
41
|
|
19
42
|
# @return [String]
|
43
|
+
#
|
44
|
+
# @api public
|
20
45
|
def name
|
21
46
|
"Map"
|
22
47
|
end
|
23
48
|
|
24
49
|
# @param [Hash] hash
|
50
|
+
#
|
25
51
|
# @return [Hash]
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
52
|
+
#
|
53
|
+
# @api private
|
54
|
+
def call_unsafe(hash)
|
55
|
+
try(hash) { |failure|
|
56
|
+
raise MapError, failure.error.message
|
57
|
+
}.input
|
30
58
|
end
|
31
|
-
alias_method :[], :call
|
32
59
|
|
33
60
|
# @param [Hash] hash
|
34
|
-
#
|
35
|
-
|
36
|
-
|
61
|
+
#
|
62
|
+
# @return [Hash]
|
63
|
+
#
|
64
|
+
# @api private
|
65
|
+
def call_safe(hash)
|
66
|
+
try(hash) { return yield }.input
|
37
67
|
end
|
38
|
-
alias_method :===, :valid?
|
39
68
|
|
40
69
|
# @param [Hash] hash
|
70
|
+
#
|
41
71
|
# @return [Result]
|
72
|
+
#
|
73
|
+
# @api public
|
42
74
|
def try(hash)
|
43
75
|
result = coerce(hash)
|
44
76
|
return result if result.success? || !block_given?
|
77
|
+
|
45
78
|
yield(result)
|
46
79
|
end
|
47
80
|
|
48
81
|
# @param meta [Boolean] Whether to dump the meta to the AST
|
82
|
+
#
|
49
83
|
# @return [Array] An AST representation
|
84
|
+
#
|
85
|
+
# @api public
|
50
86
|
def to_ast(meta: true)
|
51
87
|
[:map,
|
52
|
-
[key_type.to_ast(meta: true),
|
88
|
+
[key_type.to_ast(meta: true),
|
89
|
+
value_type.to_ast(meta: true),
|
53
90
|
meta ? self.meta : EMPTY_HASH]]
|
54
91
|
end
|
55
92
|
|
56
93
|
# @return [Boolean]
|
94
|
+
#
|
95
|
+
# @api public
|
57
96
|
def constrained?
|
58
97
|
value_type.constrained?
|
59
98
|
end
|
60
99
|
|
61
100
|
private
|
62
101
|
|
102
|
+
# @api private
|
63
103
|
def coerce(input)
|
64
|
-
|
65
|
-
|
66
|
-
|
104
|
+
unless primitive?(input)
|
105
|
+
return failure(
|
106
|
+
input, CoercionError.new("#{input.inspect} must be an instance of #{primitive}")
|
107
|
+
)
|
108
|
+
end
|
67
109
|
|
68
|
-
output
|
110
|
+
output = {}
|
111
|
+
failures = []
|
112
|
+
|
113
|
+
input.each do |k, v|
|
114
|
+
res_k = key_type.try(k)
|
115
|
+
res_v = value_type.try(v)
|
69
116
|
|
70
|
-
input.each do |k,v|
|
71
|
-
res_k = options[:key_type].try(k)
|
72
|
-
res_v = options[:value_type].try(v)
|
73
117
|
if res_k.failure?
|
74
|
-
failures <<
|
118
|
+
failures << res_k.error
|
75
119
|
elsif output.key?(res_k.input)
|
76
|
-
failures << "duplicate coerced hash key #{res_k.input.inspect}"
|
120
|
+
failures << CoercionError.new("duplicate coerced hash key #{res_k.input.inspect}")
|
77
121
|
elsif res_v.failure?
|
78
|
-
failures <<
|
122
|
+
failures << res_v.error
|
79
123
|
else
|
80
124
|
output[res_k.input] = res_v.input
|
81
125
|
end
|
82
126
|
end
|
83
127
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
def validate_options!
|
90
|
-
%i(key_type value_type).each do |opt|
|
91
|
-
type = send(opt)
|
92
|
-
next if type.is_a?(Type)
|
93
|
-
raise MapError, ":#{opt} must be a #{Type}, got: #{type.inspect}"
|
128
|
+
if failures.empty?
|
129
|
+
success(output)
|
130
|
+
else
|
131
|
+
failure(input, MultipleError.new(failures))
|
94
132
|
end
|
95
133
|
end
|
96
134
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
module Types
|
5
|
+
# Storage for meta-data
|
6
|
+
#
|
7
|
+
# @api public
|
8
|
+
module Meta
|
9
|
+
def initialize(*args, meta: EMPTY_HASH, **options)
|
10
|
+
super(*args, **options)
|
11
|
+
@meta = meta.freeze
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param options [Hash] new_options
|
15
|
+
#
|
16
|
+
# @return [Type]
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
def with(**options)
|
20
|
+
super(meta: @meta, **options)
|
21
|
+
end
|
22
|
+
|
23
|
+
# @overload meta
|
24
|
+
# @return [Hash] metadata associated with type
|
25
|
+
#
|
26
|
+
# @overload meta(data)
|
27
|
+
# @param [Hash] new metadata to merge into existing metadata
|
28
|
+
# @return [Type] new type with added metadata
|
29
|
+
#
|
30
|
+
# @api public
|
31
|
+
def meta(data = Undefined)
|
32
|
+
if Undefined.equal?(data)
|
33
|
+
@meta
|
34
|
+
elsif data.empty?
|
35
|
+
self
|
36
|
+
else
|
37
|
+
with(meta: @meta.merge(data))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Resets meta
|
42
|
+
#
|
43
|
+
# @return [Dry::Types::Type]
|
44
|
+
#
|
45
|
+
# @api public
|
46
|
+
def pristine
|
47
|
+
with(meta: EMPTY_HASH)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/dry/types/module.rb
CHANGED
@@ -1,22 +1,27 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/core/deprecations"
|
4
|
+
require "dry/types/builder_methods"
|
3
5
|
|
4
6
|
module Dry
|
5
7
|
module Types
|
6
8
|
# Export types registered in a container as module constants.
|
7
9
|
# @example
|
8
10
|
# module Types
|
9
|
-
# include Dry::Types
|
11
|
+
# include Dry::Types(:strict, :coercible, :nominal, default: :strict)
|
10
12
|
# end
|
11
|
-
#
|
13
|
+
#
|
14
|
+
# Types.constants
|
12
15
|
# # => [:Class, :Strict, :Symbol, :Integer, :Float, :String, :Array, :Hash,
|
13
16
|
# # :Decimal, :Nil, :True, :False, :Bool, :Date, :Nominal, :DateTime, :Range,
|
14
17
|
# # :Coercible, :Time]
|
18
|
+
#
|
19
|
+
# @api public
|
15
20
|
class Module < ::Module
|
16
|
-
def initialize(registry, *args)
|
21
|
+
def initialize(registry, *args, **kwargs)
|
17
22
|
@registry = registry
|
18
|
-
check_parameters(*args)
|
19
|
-
constants = type_constants(*args)
|
23
|
+
check_parameters(*args, **kwargs)
|
24
|
+
constants = type_constants(*args, **kwargs)
|
20
25
|
define_constants(constants)
|
21
26
|
extend(BuilderMethods)
|
22
27
|
|
@@ -64,7 +69,7 @@ module Dry
|
|
64
69
|
def registry_tree
|
65
70
|
@registry_tree ||= @registry.keys.each_with_object({}) { |key, tree|
|
66
71
|
type = @registry[key]
|
67
|
-
*modules, const_name = key.split(
|
72
|
+
*modules, const_name = key.split(".").map { |part|
|
68
73
|
Inflector.camelize(part).to_sym
|
69
74
|
}
|
70
75
|
next if modules.empty?
|
@@ -82,14 +87,14 @@ module Dry
|
|
82
87
|
referenced.concat(aliases.keys)
|
83
88
|
|
84
89
|
known = @registry.keys.map { |k|
|
85
|
-
ns, *path = k.split(
|
90
|
+
ns, *path = k.split(".")
|
86
91
|
ns.to_sym unless path.empty?
|
87
92
|
}.compact.uniq
|
88
93
|
|
89
94
|
(referenced.uniq - known).each do |name|
|
90
95
|
raise ArgumentError,
|
91
|
-
"#{
|
92
|
-
"Supported options are #{
|
96
|
+
"#{name.inspect} is not a known type namespace. "\
|
97
|
+
"Supported options are #{known.map(&:inspect).join(", ")}"
|
93
98
|
end
|
94
99
|
end
|
95
100
|
|
data/lib/dry/types/nominal.rb
CHANGED
@@ -1,22 +1,35 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/core/deprecations"
|
4
|
+
require "dry/core/equalizer"
|
5
|
+
require "dry/types/builder"
|
6
|
+
require "dry/types/result"
|
7
|
+
require "dry/types/options"
|
8
|
+
require "dry/types/meta"
|
5
9
|
|
6
10
|
module Dry
|
7
11
|
module Types
|
12
|
+
# Nominal types define a primitive class and do not apply any constructors or constraints
|
13
|
+
#
|
14
|
+
# Use these types for annotations and the base for building more complex types on top of them.
|
15
|
+
#
|
16
|
+
# @api public
|
8
17
|
class Nominal
|
9
18
|
include Type
|
10
19
|
include Options
|
20
|
+
include Meta
|
11
21
|
include Builder
|
12
22
|
include Printable
|
13
|
-
include Dry::Equalizer(:primitive, :options, :meta, inspect: false)
|
23
|
+
include Dry::Equalizer(:primitive, :options, :meta, inspect: false, immutable: true)
|
14
24
|
|
15
25
|
# @return [Class]
|
16
26
|
attr_reader :primitive
|
17
27
|
|
18
28
|
# @param [Class] primitive
|
29
|
+
#
|
19
30
|
# @return [Type]
|
31
|
+
#
|
32
|
+
# @api private
|
20
33
|
def self.[](primitive)
|
21
34
|
if primitive == ::Array
|
22
35
|
Types::Array
|
@@ -27,8 +40,12 @@ module Dry
|
|
27
40
|
end
|
28
41
|
end
|
29
42
|
|
43
|
+
ALWAYS = proc { true }
|
44
|
+
|
30
45
|
# @param [Type,Class] primitive
|
31
46
|
# @param [Hash] options
|
47
|
+
#
|
48
|
+
# @api private
|
32
49
|
def initialize(primitive, **options)
|
33
50
|
super
|
34
51
|
@primitive = primitive
|
@@ -36,76 +53,150 @@ module Dry
|
|
36
53
|
end
|
37
54
|
|
38
55
|
# @return [String]
|
56
|
+
#
|
57
|
+
# @api public
|
39
58
|
def name
|
40
59
|
primitive.name
|
41
60
|
end
|
42
61
|
|
43
62
|
# @return [false]
|
63
|
+
#
|
64
|
+
# @api public
|
44
65
|
def default?
|
45
66
|
false
|
46
67
|
end
|
47
68
|
|
48
69
|
# @return [false]
|
70
|
+
#
|
71
|
+
# @api public
|
49
72
|
def constrained?
|
50
73
|
false
|
51
74
|
end
|
52
75
|
|
53
76
|
# @return [false]
|
77
|
+
#
|
78
|
+
# @api public
|
54
79
|
def optional?
|
55
80
|
false
|
56
81
|
end
|
57
82
|
|
58
83
|
# @param [BasicObject] input
|
84
|
+
#
|
85
|
+
# @return [BasicObject]
|
86
|
+
#
|
87
|
+
# @api private
|
88
|
+
def call_unsafe(input)
|
89
|
+
input
|
90
|
+
end
|
91
|
+
|
92
|
+
# @param [BasicObject] input
|
93
|
+
#
|
59
94
|
# @return [BasicObject]
|
60
|
-
|
95
|
+
#
|
96
|
+
# @api private
|
97
|
+
def call_safe(input)
|
61
98
|
input
|
62
99
|
end
|
63
|
-
alias_method :[], :call
|
64
100
|
|
65
101
|
# @param [Object] input
|
66
|
-
#
|
102
|
+
#
|
67
103
|
# @yieldparam [Failure] failure
|
68
104
|
# @yieldreturn [Result]
|
105
|
+
#
|
69
106
|
# @return [Result,Logic::Result] when a block is not provided
|
70
107
|
# @return [nil] otherwise
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
failure = failure(input, "#{input.inspect} must be an instance of #{primitive}")
|
76
|
-
block ? yield(failure) : failure
|
77
|
-
end
|
108
|
+
#
|
109
|
+
# @api public
|
110
|
+
def try(input)
|
111
|
+
success(input)
|
78
112
|
end
|
79
113
|
|
80
114
|
# @param (see Dry::Types::Success#initialize)
|
115
|
+
#
|
81
116
|
# @return [Result::Success]
|
117
|
+
#
|
118
|
+
# @api public
|
82
119
|
def success(input)
|
83
120
|
Result::Success.new(input)
|
84
121
|
end
|
85
122
|
|
86
123
|
# @param (see Failure#initialize)
|
124
|
+
#
|
87
125
|
# @return [Result::Failure]
|
126
|
+
#
|
127
|
+
# @api public
|
88
128
|
def failure(input, error)
|
129
|
+
raise ArgumentError, "error must be a CoercionError" unless error.is_a?(CoercionError)
|
130
|
+
|
89
131
|
Result::Failure.new(input, error)
|
90
132
|
end
|
91
133
|
|
92
134
|
# Checks whether value is of a #primitive class
|
135
|
+
#
|
93
136
|
# @param [Object] value
|
137
|
+
#
|
94
138
|
# @return [Boolean]
|
139
|
+
#
|
140
|
+
# @api public
|
95
141
|
def primitive?(value)
|
96
142
|
value.is_a?(primitive)
|
97
143
|
end
|
98
|
-
|
99
|
-
|
144
|
+
|
145
|
+
# @api private
|
146
|
+
def coerce(input, &_block)
|
147
|
+
if primitive?(input)
|
148
|
+
input
|
149
|
+
elsif block_given?
|
150
|
+
yield
|
151
|
+
else
|
152
|
+
raise CoercionError, "#{input.inspect} must be an instance of #{primitive}"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# @api private
|
157
|
+
def try_coerce(input)
|
158
|
+
result = success(input)
|
159
|
+
|
160
|
+
coerce(input) do
|
161
|
+
result = failure(
|
162
|
+
input,
|
163
|
+
CoercionError.new("#{input.inspect} must be an instance of #{primitive}")
|
164
|
+
)
|
165
|
+
end
|
166
|
+
|
167
|
+
if block_given?
|
168
|
+
yield(result)
|
169
|
+
else
|
170
|
+
result
|
171
|
+
end
|
172
|
+
end
|
100
173
|
|
101
174
|
# Return AST representation of a type nominal
|
102
175
|
#
|
103
|
-
# @api public
|
104
|
-
#
|
105
176
|
# @return [Array]
|
177
|
+
#
|
178
|
+
# @api public
|
106
179
|
def to_ast(meta: true)
|
107
180
|
[:nominal, [primitive, meta ? self.meta : EMPTY_HASH]]
|
108
181
|
end
|
182
|
+
|
183
|
+
# Return self. Nominal types are lax by definition
|
184
|
+
#
|
185
|
+
# @return [Nominal]
|
186
|
+
#
|
187
|
+
# @api public
|
188
|
+
def lax
|
189
|
+
self
|
190
|
+
end
|
191
|
+
|
192
|
+
# Wrap the type with a proc
|
193
|
+
#
|
194
|
+
# @return [Proc]
|
195
|
+
#
|
196
|
+
# @api public
|
197
|
+
def to_proc
|
198
|
+
ALWAYS
|
199
|
+
end
|
109
200
|
end
|
110
201
|
|
111
202
|
extend Dry::Core::Deprecations[:'dry-types']
|
@@ -114,6 +205,6 @@ module Dry
|
|
114
205
|
end
|
115
206
|
end
|
116
207
|
|
117
|
-
require
|
118
|
-
require
|
119
|
-
require
|
208
|
+
require "dry/types/array"
|
209
|
+
require "dry/types/hash"
|
210
|
+
require "dry/types/map"
|
data/lib/dry/types/options.rb
CHANGED
@@ -1,42 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dry
|
2
4
|
module Types
|
5
|
+
# Common API for types with options
|
6
|
+
#
|
7
|
+
# @api private
|
3
8
|
module Options
|
4
9
|
# @return [Hash]
|
5
10
|
attr_reader :options
|
6
11
|
|
7
12
|
# @see Nominal#initialize
|
8
|
-
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def initialize(*args, **options)
|
9
16
|
@__args__ = args.freeze
|
10
17
|
@options = options.freeze
|
11
|
-
@meta = meta.freeze
|
12
18
|
end
|
13
19
|
|
14
20
|
# @param [Hash] new_options
|
21
|
+
#
|
15
22
|
# @return [Type]
|
16
|
-
def with(**new_options)
|
17
|
-
self.class.new(*@__args__, **options, meta: @meta, **new_options)
|
18
|
-
end
|
19
|
-
|
20
|
-
# @overload meta
|
21
|
-
# @return [Hash] metadata associated with type
|
22
23
|
#
|
23
|
-
# @
|
24
|
-
|
25
|
-
|
26
|
-
def meta(data = nil)
|
27
|
-
if !data
|
28
|
-
@meta
|
29
|
-
elsif data.empty?
|
30
|
-
self
|
31
|
-
else
|
32
|
-
with(meta: @meta.merge(data))
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# Resets meta
|
37
|
-
# @return [Dry::Types::Type]
|
38
|
-
def pristine
|
39
|
-
with(meta: EMPTY_HASH)
|
24
|
+
# @api private
|
25
|
+
def with(**new_options)
|
26
|
+
self.class.new(*@__args__, **options, **new_options)
|
40
27
|
end
|
41
28
|
end
|
42
29
|
end
|