
gems.coercible-1.0.0.lib.coercible.coercer.rb Maven / Gradle / Ivy
The newest version!
module Coercible
# Coercer object
#
#
# @example
#
# coercer = Coercible::Coercer.new
#
# coercer[String].to_boolean('yes') # => true
# coercer[Integer].to_string(1) # => '1'
#
# @api public
class Coercer
# Return coercer instances
#
# @return [Array]
#
# @api private
attr_reader :coercers
# Returns global configuration for coercers
#
# @return [Configuration]
#
# @api private
attr_reader :config
# Build a new coercer
#
# @example
#
# Coercible::Coercer.new { |config| # set configuration }
#
# @yieldparam [Configuration]
#
# @return [Coercer]
#
# @api public
def self.new(&block)
configuration = Configuration.build(config_keys)
configurable_coercers.each do |coercer|
configuration.send("#{coercer.config_name}=", coercer.config)
end
yield(configuration) if block_given?
super(configuration)
end
# Return configuration keys for Coercer instance
#
# @return [Array]
#
# @api private
def self.config_keys
configurable_coercers.map(&:config_name)
end
private_class_method :config_keys
# Return coercer classes that are configurable
#
# @return [Array]
#
# @api private
def self.configurable_coercers(&block)
Coercer::Object.descendants.select { |descendant|
descendant.respond_to?(:config)
}
end
private_class_method :configurable_coercers
# Initialize a new coercer instance
#
# @param [Hash] coercers
#
# @param [Configuration] config
#
# @return [undefined]
#
# @api private
def initialize(config, coercers = {})
@coercers = coercers
@config = config
end
# Access a specific coercer object for the given type
#
# @example
#
# coercer[String] # => string coercer
# coercer[Integer] # => integer coercer
#
# @param [Class] type
#
# @return [Coercer::Object]
#
# @api public
def [](klass)
coercers[klass] || initialize_coercer(klass)
end
private
# Initialize a new coercer instance for the given type
#
# If a coercer class supports configuration it will receive it from the
# global configuration object
#
# @return [Coercer::Object]
#
# @api private
def initialize_coercer(klass)
coercers[klass] =
begin
coercer = Coercer::Object.determine_type(klass) || Coercer::Object
args = [ self ]
args << config_for(coercer) if coercer.respond_to?(:config_name)
coercer.new(*args)
end
end
# Find configuration for the given coercer type
#
# @return [Configuration]
#
# @api private
def config_for(coercer)
config.send(coercer.config_name)
end
end # class Coercer
end # module Coercible
© 2015 - 2025 Weber Informatics LLC | Privacy Policy