class Dry::Types::Constructor
Constructor
types apply a function to the input that is supposed to return a new value. Coercion is a common use case for constructor types.
@api public
@api public
Attributes
@return [#call]
@return [Type]
Public Class Methods
@param [Builder, Object] input @param [Hash] options @param [#call, nil] block
@api public
# File lib/dry/types/constructor.rb, line 35 def self.[](type, fn:, **options) function = Function[fn] if function.wrapper? wrapper_type.new(type, fn: function, **options) else new(type, fn: function, **options) end end
@param [Builder, Object] input @param [Hash] options @param [#call, nil] block
@api public
# File lib/dry/types/constructor.rb, line 25 def self.new(input, fn: Undefined, **options, &block) type = input.is_a?(Builder) ? input : Nominal.new(input) super(type, **options, fn: Function[Undefined.default(fn, block)]) end
Instantiate a new constructor type instance
@param [Type] type @param [Function] fn @param [Hash] options
@api private
# File lib/dry/types/constructor.rb, line 62 def initialize(type, fn: nil, **options) @type = type @fn = fn super(type, **options, fn: fn) end
@api private
# File lib/dry/types/constructor.rb, line 46 def self.wrapper_type @wrapper_type ||= if self < Wrapper self else const_set(:Wrapping, ::Class.new(self).include(Wrapper)) end end
Public Instance Methods
@return [Object]
@api private
# File lib/dry/types/constructor.rb, line 72 def call_safe(input) coerced = fn.(input) { |output = input| return yield(output) } type.call_safe(coerced) { |output = coerced| yield(output) } end
@return [Object]
@api private
# File lib/dry/types/constructor.rb, line 80 def call_unsafe(input) type.call_unsafe(fn.(input)) end
@return [Class]
@api private
# File lib/dry/types/constructor.rb, line 124 def constrained_type Constrained::Coercible end
Build a new constructor by appending a block to the coercion function
@param [#call, nil] new_fn @param [Hash] options @param [#call, nil] block
@return [Constructor]
@api public
# File lib/dry/types/constructor.rb, line 109 def constructor(new_fn = nil, **options, &block) next_fn = Function[new_fn || block] if next_fn.wrapper? self.class.wrapper_type.new(with(**options), fn: next_fn) else with(**options, fn: fn >> next_fn) end end
Build a lax type
@return [Lax] @api public
# File lib/dry/types/constructor.rb, line 153 def lax Lax.new(constructor_type[type.lax, **options]) end
Build a new constructor by prepending a block to the coercion function
@param [#call, nil] new_fn @param [Hash] options @param [#call, nil] block
@return [Constructor]
@api public
# File lib/dry/types/constructor.rb, line 144 def prepend(new_fn = nil, **options, &block) with(**options, fn: fn << (new_fn || block)) end
@see Nominal#to_ast
@api public
# File lib/dry/types/constructor.rb, line 131 def to_ast(meta: true) [:constructor, [type.to_ast(meta: meta), fn.to_ast]] end
Wrap the type with a proc
@return [Proc]
@api public
# File lib/dry/types/constructor.rb, line 162 def to_proc proc { |value| self.(value) } end
@param [Object] input @param [#call,nil] block
@return [Logic::Result, Types::Result
] @return [Object] if block given and try fails
@api public
# File lib/dry/types/constructor.rb, line 91 def try(input, &block) value = fn.(input) rescue CoercionError => e failure = failure(input, e) block_given? ? yield(failure) : failure else type.try(value, &block) end
Private Instance Methods
Delegates missing methods to {#type}
@param [Symbol] method @param [Array] args @param [#call, nil] block
@api private
# File lib/dry/types/constructor.rb, line 184 def method_missing(method, *args, &block) if type.respond_to?(method) response = type.public_send(method, *args, &block) if response.is_a?(Type) && response.instance_of?(type.class) response.constructor_type[response, **options] else response end else super end end
@param [Symbol] meth @param [Boolean] include_private @return [Boolean]
@api private
# File lib/dry/types/constructor.rb, line 173 def respond_to_missing?(meth, include_private = false) super || type.respond_to?(meth) end