dry-types 0.9.2 → 0.9.3

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.
@@ -2,6 +2,11 @@ module Dry
2
2
  module Types
3
3
  class Constrained
4
4
  class Coercible < Constrained
5
+ # @param [Object] input
6
+ # @param [#call] block
7
+ # @yieldparam [Failure] failure
8
+ # @yieldreturn [Result]
9
+ # @return [Result]
5
10
  def try(input, &block)
6
11
  result = type.try(input)
7
12
 
@@ -4,12 +4,15 @@ require 'dry/logic/rule/predicate'
4
4
 
5
5
  module Dry
6
6
  module Types
7
+ # @param [Hash] options
8
+ # @return [Dry::Logic::Rule]
7
9
  def self.Rule(options)
8
10
  rule_compiler.(
9
11
  options.map { |key, val| Logic::Rule::Predicate.new(Logic::Predicates[:"#{key}?"]).curry(val).to_ast }
10
12
  ).reduce(:and)
11
13
  end
12
14
 
15
+ # @return [Dry::Logic::RuleCompiler]
13
16
  def self.rule_compiler
14
17
  @rule_compiler ||= Logic::RuleCompiler.new(Logic::Predicates)
15
18
  end
@@ -5,36 +5,54 @@ module Dry
5
5
  class Constructor < Definition
6
6
  include Dry::Equalizer(:type)
7
7
 
8
+ # @return [#call]
8
9
  attr_reader :fn
9
10
 
11
+ # @return [Definition]
10
12
  attr_reader :type
11
13
 
14
+ # @param [Builder, Object] input
15
+ # @param [Hash] options
16
+ # @param [#call] block
12
17
  def self.new(input, options = {}, &block)
13
18
  type = input.is_a?(Builder) ? input : Definition.new(input)
14
19
  super(type, options, &block)
15
20
  end
16
21
 
22
+ # @param [Definition] type
23
+ # @param [Hash] options
24
+ # @param [#proc] block
17
25
  def initialize(type, options = {}, &block)
18
26
  @type = type
19
27
  @fn = options.fetch(:fn, block)
20
28
  super
21
29
  end
22
30
 
31
+ # @return [Class]
23
32
  def primitive
24
33
  type.primitive
25
34
  end
26
35
 
36
+ # @param [Object] input
37
+ # @return [Object]
27
38
  def call(input)
28
39
  type[fn[input]]
29
40
  end
30
41
  alias_method :[], :call
31
42
 
43
+ # @param [Object] input
44
+ # @param [#call] block
45
+ # @return [Result]
32
46
  def try(input, &block)
33
47
  type.try(fn[input], &block)
34
48
  rescue TypeError => e
35
49
  failure(input, e.message)
36
50
  end
37
51
 
52
+ # @param [#call, nil] new_fn
53
+ # @param [Hash] options
54
+ # @param [#call] block
55
+ # @return [Constructor]
38
56
  def constructor(new_fn = nil, **options, &block)
39
57
  left = new_fn || block
40
58
  right = fn
@@ -42,20 +60,30 @@ module Dry
42
60
  with(options.merge(fn: -> input { left[right[input]] }))
43
61
  end
44
62
 
63
+ # @param [Object] value
64
+ # @return [Boolean]
45
65
  def valid?(value)
46
66
  super && type.valid?(value)
47
67
  end
48
68
 
69
+ # @return [Class]
49
70
  def constrained_type
50
71
  Constrained::Coercible
51
72
  end
52
73
 
53
74
  private
54
75
 
76
+ # @param [Symbol] meth
77
+ # @param [Boolean] include_private
78
+ # @return [Boolean]
55
79
  def respond_to_missing?(meth, include_private = false)
56
80
  super || type.respond_to?(meth)
57
81
  end
58
82
 
83
+ # Delegates missing methods to {#type}
84
+ # @param [Symbol] meth
85
+ # @param [Array] args
86
+ # @param [#call] block
59
87
  def method_missing(meth, *args, &block)
60
88
  if type.respond_to?(meth)
61
89
  response = type.__send__(meth, *args, &block)
@@ -5,43 +5,62 @@ module Dry
5
5
  module Decorator
6
6
  include Options
7
7
 
8
+ # @return [Definition]
8
9
  attr_reader :type
9
10
 
11
+ # @param [Definition] type
10
12
  def initialize(type, *)
11
13
  super
12
14
  @type = type
13
15
  end
14
16
 
17
+ # @return [Constructor]
15
18
  def constructor
16
19
  type.constructor
17
20
  end
18
21
 
22
+ # @param [Object] input
23
+ # @param [#call] block
24
+ # @return [Result]
19
25
  def try(input, &block)
20
26
  type.try(input, &block)
21
27
  end
22
28
 
29
+ # @param [Object] value
30
+ # @return [Boolean]
23
31
  def valid?(value)
24
32
  type.valid?(value)
25
33
  end
26
34
 
35
+ # @return [Boolean]
27
36
  def default?
28
37
  type.default?
29
38
  end
30
39
 
40
+ # @return [Boolean]
31
41
  def constrained?
32
42
  type.constrained?
33
43
  end
34
44
 
45
+ # @param [Symbol] meth
46
+ # @param [Boolean] include_private
47
+ # @return [Boolean]
35
48
  def respond_to_missing?(meth, include_private = false)
36
49
  super || type.respond_to?(meth)
37
50
  end
38
51
 
39
52
  private
40
53
 
54
+ # @param [Object] response
55
+ # @return [Boolean]
41
56
  def decorate?(response)
42
57
  response.kind_of?(type.class)
43
58
  end
44
59
 
60
+ # Delegates missing methods to {#type}
61
+ # @param [Symbol] meth
62
+ # @param [Array] args
63
+ # @param [#call] block
45
64
  def method_missing(meth, *args, &block)
46
65
  if type.respond_to?(meth)
47
66
  response = type.__send__(meth, *args, &block)
@@ -10,15 +10,20 @@ module Dry
10
10
  class Callable < Default
11
11
  include Dry::Equalizer(:type, :options)
12
12
 
13
+ # Evaluates given callable
14
+ # @return [Object]
13
15
  def evaluate
14
16
  value.call
15
17
  end
16
18
  end
17
19
 
20
+ # @return [Object]
18
21
  attr_reader :value
19
22
 
20
23
  alias_method :evaluate, :value
21
24
 
25
+ # @param [Object, #call] value
26
+ # @return [Default, Dry::Types::Default::Callable]
22
27
  def self.[](value)
23
28
  if value.respond_to?(:call)
24
29
  Callable
@@ -27,23 +32,32 @@ module Dry
27
32
  end
28
33
  end
29
34
 
35
+ # @param [Definition] type
36
+ # @param [Object] value
30
37
  def initialize(type, value, *)
31
38
  super
32
39
  @value = value
33
40
  end
34
41
 
42
+ # @param [Array] args see {Dry::Types::Builder#constrained}
43
+ # @return [Default]
35
44
  def constrained(*args)
36
45
  type.constrained(*args).default(value)
37
46
  end
38
47
 
48
+ # @return [true]
39
49
  def default?
40
50
  true
41
51
  end
42
52
 
53
+ # @param [Object] input
54
+ # @return [Success]
43
55
  def try(input)
44
56
  success(call(input))
45
57
  end
46
58
 
59
+ # @param [Object] input
60
+ # @return [Object] value passed through {#type} or {#default} value
47
61
  def call(input)
48
62
  if input.nil?
49
63
  evaluate
@@ -9,10 +9,14 @@ module Dry
9
9
  include Options
10
10
  include Builder
11
11
 
12
+ # @return [Hash]
12
13
  attr_reader :options
13
14
 
15
+ # @return [Class]
14
16
  attr_reader :primitive
15
17
 
18
+ # @param [Class] primitive
19
+ # @return [Definition]
16
20
  def self.[](primitive)
17
21
  if primitive == ::Array
18
22
  Types::Array
@@ -23,29 +27,41 @@ module Dry
23
27
  end
24
28
  end
25
29
 
30
+ # @param [Class] primitive
31
+ # @param [Hash] options
26
32
  def initialize(primitive, options = {})
27
33
  super
28
34
  @primitive = primitive
29
35
  freeze
30
36
  end
31
37
 
38
+ # @return [String]
32
39
  def name
33
40
  primitive.name
34
41
  end
35
42
 
43
+ # @return [false]
36
44
  def default?
37
45
  false
38
46
  end
39
47
 
48
+ # @return [false]
40
49
  def constrained?
41
50
  false
42
51
  end
43
52
 
53
+ # @param [Object] input
54
+ # @return [Object]
44
55
  def call(input)
45
56
  input
46
57
  end
47
58
  alias_method :[], :call
48
59
 
60
+ # @param [Object] input
61
+ # @param [#call] block
62
+ # @yieldparam [Failure] failure
63
+ # @yieldreturn [Result]
64
+ # @return [Result]
49
65
  def try(input, &block)
50
66
  if valid?(input)
51
67
  success(input)
@@ -55,18 +71,29 @@ module Dry
55
71
  end
56
72
  end
57
73
 
58
- def success(*args)
59
- Result::Success.new(*args)
74
+ # @param (see Dry::Types::Success#initialize)
75
+ # @return [Success]
76
+ def success(input)
77
+ Result::Success.new(input)
60
78
  end
61
79
 
62
- def failure(*args)
63
- Result::Failure.new(*args)
80
+
81
+ # @param (see Failure#initialize)
82
+ # @return [Failure]
83
+ def failure(input, error)
84
+ Result::Failure.new(input, error)
64
85
  end
65
86
 
87
+ # @param [Object] klass class of the result instance
88
+ # @param [Array] args arguments for the +klass#initialize+ method
89
+ # @return [Object] new instance of the given +klass+
66
90
  def result(klass, *args)
67
91
  klass.new(*args)
68
92
  end
69
93
 
94
+ # Checks whether value is of a #primitive class
95
+ # @param [Object] value
96
+ # @return [Boolean]
70
97
  def primitive?(value)
71
98
  value.is_a?(primitive)
72
99
  end
@@ -6,8 +6,15 @@ module Dry
6
6
  include Dry::Equalizer(:type, :options, :values)
7
7
  include Decorator
8
8
 
9
- attr_reader :values, :mapping
9
+ # @return [Array]
10
+ attr_reader :values
10
11
 
12
+ # @return [Hash]
13
+ attr_reader :mapping
14
+
15
+ # @param [Definition] type
16
+ # @param [Hash] options
17
+ # @option options [Array] :values
11
18
  def initialize(type, options)
12
19
  super
13
20
  @values = options.fetch(:values).freeze
@@ -15,6 +22,8 @@ module Dry
15
22
  @mapping = values.each_with_object({}) { |v, h| h[values.index(v)] = v }.freeze
16
23
  end
17
24
 
25
+ # @param [Object] input
26
+ # @return [Object]
18
27
  def call(input)
19
28
  value =
20
29
  if values.include?(input)
@@ -2,9 +2,13 @@ module Dry
2
2
  module Types
3
3
  extend Dry::Configurable
4
4
 
5
+ # @!attribute [r] namespace
6
+ # @return [Container{String => Definition}]
5
7
  setting :namespace, self
6
8
 
7
9
  class SchemaError < TypeError
10
+ # @param [String] key
11
+ # @param [Object] value
8
12
  def initialize(key, value)
9
13
  super("#{value.inspect} (#{value.class}) has invalid type for :#{key}")
10
14
  end
@@ -14,20 +18,27 @@ module Dry
14
18
  private_constant(:SchemaKeyError)
15
19
 
16
20
  class MissingKeyError < SchemaKeyError
21
+ # @param [String] key
17
22
  def initialize(key)
18
23
  super(":#{key} is missing in Hash input")
19
24
  end
20
25
  end
21
26
 
22
27
  class UnknownKeysError < SchemaKeyError
28
+ # @param [<String, Symbol>] keys
23
29
  def initialize(*keys)
24
30
  super("unexpected keys #{keys.inspect} in Hash input")
25
31
  end
26
32
  end
27
33
 
28
- ConstraintError = Class.new(TypeError) do
29
- attr_reader :result, :input
34
+ class ConstraintError < TypeError
35
+ # @return [String, #to_s]
36
+ attr_reader :result
37
+ # @return [Object]
38
+ attr_reader :input
30
39
 
40
+ # @param [String, #to_s] result
41
+ # @param [Object] input
31
42
  def initialize(result, input)
32
43
  @result = result
33
44
  @input = input
@@ -39,6 +50,7 @@ module Dry
39
50
  end
40
51
  end
41
52
 
53
+ # @return [String]
42
54
  def to_s
43
55
  "#{input.inspect} violates constraints (#{result} failed)"
44
56
  end
@@ -9,19 +9,27 @@ module Dry
9
9
  include Builder
10
10
  include Dry::Monads::Maybe::Mixin
11
11
 
12
+ # @param [Dry::Monads::Maybe, Object] input
13
+ # @return [Dry::Monads::Maybe]
12
14
  def call(input)
13
15
  input.is_a?(Dry::Monads::Maybe) ? input : Maybe(type[input])
14
16
  end
15
17
  alias_method :[], :call
16
18
 
19
+ # @param [Object] input
20
+ # @return [Result::Success]
17
21
  def try(input)
18
22
  Result::Success.new(Maybe(type[input]))
19
23
  end
20
24
 
25
+ # @return [true]
21
26
  def maybe?
22
27
  true
23
28
  end
24
29
 
30
+ # @param [Object] value
31
+ # @see Dry::Types::Builder#default
32
+ # @raise [ArgumentError] if nil provided as default value
25
33
  def default(value)
26
34
  if value.nil?
27
35
  raise ArgumentError, "nil cannot be used as a default of a maybe type"
@@ -32,6 +40,7 @@ module Dry
32
40
  end
33
41
 
34
42
  module Builder
43
+ # @return [Maybe]
35
44
  def maybe
36
45
  Maybe.new(Types['strict.nil'] | self)
37
46
  end
@@ -39,6 +48,9 @@ module Dry
39
48
 
40
49
  class Hash
41
50
  module MaybeTypes
51
+ # @param [Hash] result
52
+ # @param [Symbol] key
53
+ # @param [Definition] type
42
54
  def resolve_missing_value(result, key, type)
43
55
  if type.respond_to?(:maybe?) && type.maybe?
44
56
  result[key] = type[nil]
@@ -48,8 +60,13 @@ module Dry
48
60
  end
49
61
  end
50
62
 
51
- StrictWithDefaults.include MaybeTypes
52
- Schema.include MaybeTypes
63
+ class StrictWithDefaults < Strict
64
+ include MaybeTypes
65
+ end
66
+
67
+ class Schema < Hash
68
+ include MaybeTypes
69
+ end
53
70
  end
54
71
 
55
72
  # Register non-coercible maybe types