114 lines
2.1 KiB
Ruby
114 lines
2.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'dry/types/options'
|
|
|
|
module Dry
|
|
module Types
|
|
# Common API for types
|
|
#
|
|
# @api public
|
|
module Decorator
|
|
include Options
|
|
|
|
# @return [Type]
|
|
attr_reader :type
|
|
|
|
# @param [Type] type
|
|
def initialize(type, *)
|
|
super
|
|
@type = type
|
|
end
|
|
|
|
# @param [Object] input
|
|
# @param [#call, nil] block
|
|
#
|
|
# @return [Result,Logic::Result]
|
|
# @return [Object] if block given and try fails
|
|
#
|
|
# @api public
|
|
def try(input, &block)
|
|
type.try(input, &block)
|
|
end
|
|
|
|
# @return [Boolean]
|
|
#
|
|
# @api public
|
|
def default?
|
|
type.default?
|
|
end
|
|
|
|
# @return [Boolean]
|
|
#
|
|
# @api public
|
|
def constrained?
|
|
type.constrained?
|
|
end
|
|
|
|
# @return [Sum]
|
|
#
|
|
# @api public
|
|
def optional
|
|
Types['strict.nil'] | self
|
|
end
|
|
|
|
# @param [Symbol] meth
|
|
# @param [Boolean] include_private
|
|
#
|
|
# @return [Boolean]
|
|
#
|
|
# @api public
|
|
def respond_to_missing?(meth, include_private = false)
|
|
super || type.respond_to?(meth)
|
|
end
|
|
|
|
# Wrap the type with a proc
|
|
#
|
|
# @return [Proc]
|
|
#
|
|
# @api public
|
|
def to_proc
|
|
proc { |value| self.(value) }
|
|
end
|
|
|
|
private
|
|
|
|
# @param [Object] response
|
|
#
|
|
# @return [Boolean]
|
|
#
|
|
# @api private
|
|
def decorate?(response)
|
|
response.is_a?(type.class)
|
|
end
|
|
|
|
# Delegates missing methods to {#type}
|
|
#
|
|
# @param [Symbol] meth
|
|
# @param [Array] args
|
|
# @param [#call, nil] block
|
|
#
|
|
# @api private
|
|
def method_missing(meth, *args, &block)
|
|
if type.respond_to?(meth)
|
|
response = type.__send__(meth, *args, &block)
|
|
|
|
if decorate?(response)
|
|
__new__(response)
|
|
else
|
|
response
|
|
end
|
|
else
|
|
super
|
|
end
|
|
end
|
|
|
|
# Replace underlying type
|
|
#
|
|
# @api private
|
|
def __new__(type)
|
|
self.class.new(type, *@__args__[1..-1], **@options)
|
|
end
|
|
end
|
|
end
|
|
end
|