Repository URL to install this package:
|
Version:
0.14.1 ▾
|
require 'dry/types/decorator'
require 'dry/types/constraints'
require 'dry/types/constrained/coercible'
module Dry
module Types
class Constrained
include Type
include Dry::Equalizer(:type, :options, :rule, :meta)
include Decorator
include Builder
# @return [Dry::Logic::Rule]
attr_reader :rule
# @param [Type] type
# @param [Hash] options
def initialize(type, options)
super
@rule = options.fetch(:rule)
end
# @param [Object] input
# @return [Object]
# @raise [ConstraintError]
def call(input)
try(input) do |result|
raise ConstraintError.new(result, input)
end.input
end
alias_method :[], :call
# @param [Object] input
# @param [#call,nil] block
# @yieldparam [Failure] failure
# @yieldreturn [Result]
# @return [Logic::Result, Result]
# @return [Object] if block given and try fails
def try(input, &block)
result = rule.(input)
if result.success?
type.try(input, &block)
else
failure = failure(input, result)
block ? yield(failure) : failure
end
end
# @param [Object] value
# @return [Boolean]
def valid?(value)
rule.(value).success? && type.valid?(value)
end
# @param [Hash] options
# The options hash provided to {Types.Rule} and combined
# using {&} with previous {#rule}
# @return [Constrained]
# @see Dry::Logic::Operators#and
def constrained(options)
with(rule: rule & Types.Rule(options))
end
# @return [true]
def constrained?
true
end
# @param [Object] value
# @return [Boolean]
def ===(value)
valid?(value)
end
# @api public
#
# @see Definition#to_ast
def to_ast(meta: true)
[:constrained, [type.to_ast(meta: meta),
rule.to_ast,
meta ? self.meta : EMPTY_HASH]]
end
private
# @param [Object] response
# @return [Boolean]
def decorate?(response)
super || response.kind_of?(Constructor)
end
end
end
end