lib/parameters/param.rb in parameters-0.1.9 vs lib/parameters/param.rb in parameters-0.2.0
- old
+ new
@@ -1,25 +1,340 @@
+require 'set'
+require 'uri'
+require 'date'
+
module Parameters
class Param
# Name of parameter
attr_reader :name
+ # Enforced type of the parameter
+ attr_reader :type
+
# Description of parameter
attr_reader :description
#
# Creates a new Param object.
#
# @param [Symbol, String] name
# The name of the parameter.
#
+ # @param [Class] type
+ # The enforced type of the parameter.
+ #
# @param [String, nil] description
# The description of the parameter.
#
- def initialize(name,description=nil)
+ def initialize(name,type=nil,description=nil)
@name = name.to_sym
+ @type = type
@description = description
+ end
+
+ protected
+
+ # Type classes and their coercion methods
+ TYPE_COERSION = {
+ Set => :coerce_set,
+ Array => :coerce_array,
+ URI => :coerce_uri,
+ Regexp => :coerce_regexp,
+ DateTime => :coerce_date,
+ Date => :coerce_date,
+ Symbol => :coerce_symbol,
+ String => :coerce_string,
+ Integer => :coerce_integer,
+ Float => :coerce_float,
+ true => :coerce_boolean
+ }
+
+ #
+ # Coerces a given value into a specific type.
+ #
+ # @param [Class] type
+ # The type to coerce the value into.
+ #
+ # @param [Object] value
+ # The value to coerce.
+ #
+ # @return [Object]
+ # The coerced value.
+ #
+ # @since 0.2.0
+ #
+ def coerce_type(type,value)
+ if value.nil?
+ nil
+ elsif type.kind_of?(Set)
+ coerce_array(Array,value).map { |element|
+ coerce_type(type.first,element)
+ }.to_set
+ elsif type.kind_of?(Array)
+ coerce_array(Array,value).map do |element|
+ coerce_type(type.first,element)
+ end
+ elsif (method_name = TYPE_COERSION[type])
+ self.send(method_name,type,value)
+ else
+ value
+ end
+ end
+
+ #
+ # Coerces a given value into the `type` of the param.
+ #
+ # @param [Object] value
+ # The value to coerce.
+ #
+ # @return [Object]
+ # The coerced value.
+ #
+ # @since 0.2.0
+ #
+ def coerce(value)
+ coerce_type(@type,value)
+ end
+
+ #
+ # Coerces a given value into a `Set`.
+ #
+ # @param [Set[Class]] type
+ # An optional `Set` containing the type to coerce the elements
+ # of the given value to.
+ #
+ # @param [Enumerable, Object] value
+ # The value to coerce into a `Set`.
+ #
+ # @return [Set]
+ # The coerced value.
+ #
+ # @since 0.2.0
+ #
+ def coerce_set(type,value)
+ if value.kind_of?(Set)
+ value
+ elsif (value.kind_of?(Enumerable) || value.respond_to?(:to_set))
+ value.to_set
+ else
+ Set[value]
+ end
+ end
+
+ #
+ # Coerces a given value into an `Array`.
+ #
+ # @param [Array[Class]] type
+ # An optional `Array` containing the type to coerce the elements
+ # of the given value to.
+ #
+ # @param [Enumerable, Object] value
+ # The value to coerce into an `Array`.
+ #
+ # @return [Array]
+ # The coerced value.
+ #
+ # @since 0.2.0
+ #
+ def coerce_array(type,value)
+ if value.kind_of?(Array)
+ value
+ elsif (value.kind_of?(Enumerable) || value.respond_to?(:to_a))
+ value.to_a
+ else
+ [value]
+ end
+ end
+
+ #
+ # Coerces a given value into a `URI`.
+ #
+ # @param [Class] type
+ # The `URI` type to coerce to.
+ #
+ # @param [URI::Generic, #to_s] value
+ # The value to coerce into a `URI`.
+ #
+ # @return [URI::Generic]
+ # The coerced value.
+ #
+ # @since 0.2.0
+ #
+ def coerce_uri(type,value)
+ if value.kind_of?(type)
+ value
+ else
+ URI.parse(value.to_s)
+ end
+ end
+
+ #
+ # Coerces a given value into a `Regexp`.
+ #
+ # @param [Class] type
+ # The `Regexp` type to coerce to.
+ #
+ # @param [Regexp, #to_s] value
+ # The value to coerce into a `Regexp`.
+ #
+ # @return [Regexp]
+ # The coerced value.
+ #
+ # @since 0.2.0
+ #
+ def coerce_regexp(type,value)
+ if value.kind_of?(Regexp)
+ value
+ else
+ Regexp.new(value.to_s)
+ end
+ end
+
+ #
+ # Coerces a given value into a `Symbol`.
+ #
+ # @param [Class] type
+ # The `Symbol` class.
+ #
+ # @param [#to_s] value
+ # The value to coerce.
+ #
+ # @return [Symbol]
+ # The coerced value.
+ #
+ # @since 0.2.0
+ #
+ def coerce_symbol(type,value)
+ if value.kind_of?(type)
+ value
+ else
+ value.to_s.to_sym
+ end
+ end
+
+ #
+ # Coerces a given value into a `String`.
+ #
+ # @param [Class] type
+ # The `String` class.
+ #
+ # @param [#to_s] value
+ # The value to coerce into a `String`.
+ #
+ # @return [String]
+ # The coerced value.
+ #
+ # @since 0.2.0
+ #
+ def coerce_string(type,value)
+ if value.kind_of?(type)
+ value
+ else
+ value.to_s
+ end
+ end
+
+ #
+ # Coerces a given value into an `Integer`.
+ #
+ # @param [Class]
+ # The Integer class.
+ #
+ # @param [String, #to_i] value
+ # The value to coerce into an `Integer`.
+ #
+ # @return [Integer]
+ # The coerced value.
+ #
+ # @since 0.2.0
+ #
+ def coerce_integer(type,value)
+ if value.kind_of?(type)
+ value
+ elsif value.kind_of?(String)
+ base = if value[0..1] == '0x'
+ 16
+ elsif value[0..0] == '0'
+ 8
+ else
+ 10
+ end
+
+ value.to_i(base)
+ elsif value.respond_to?(:to_i)
+ value.to_i
+ else
+ 0
+ end
+ end
+
+ #
+ # Coerces a given value into a `Float`.
+ #
+ # @param [Class] type
+ # The `Float` class.
+ #
+ # @param [String, #to_f] value
+ # The value to coerce into a `Float`.
+ #
+ # @return [Float]
+ # The coerced value.
+ #
+ # @since 0.2.0
+ #
+ def coerce_float(type,value)
+ if value.kind_of?(type)
+ value
+ elsif (value.kind_of?(String) || value.respond_to?(:to_f))
+ value.to_f
+ else
+ 0.0
+ end
+ end
+
+ #
+ # Coerces a given value into a `DateTime` or `Date`.
+ #
+ # @param [Class] type
+ # The `DateTime` or `Date` class.
+ #
+ # @param [#to_s] value
+ # The value to coerce into either a `Date` or `DateTime` object.
+ #
+ # @return [DateTime, Date]
+ # The coerced value.
+ #
+ # @since 0.2.0
+ #
+ def coerce_date(type,value)
+ if value.kind_of?(type)
+ value
+ else
+ type.parse(value.to_s)
+ end
+ end
+
+ #
+ # Coerces a given value into either a `true` or `false` value.
+ #
+ # @param [true] type
+ #
+ # @param [TrueClass, FalseClass, String, Symbol] value
+ # The value to coerce into either a `true` or `false` value.
+ #
+ # @return [TrueClass, FalseClass]
+ # The coerced value.
+ #
+ # @since 0.2.0
+ #
+ def coerce_boolean(type,value)
+ case value
+ when FalseClass, NilClass, 'false', :false
+ false
+ else
+ true
+ end
end
end
end