lib/configure_me/setting.rb in configure_me-0.3.2 vs lib/configure_me/setting.rb in configure_me-0.4.0

- old
+ new

@@ -1,28 +1,77 @@ +require 'active_support/core_ext/object/blank' + module ConfigureMe + class InvalidDefault < StandardError; end + class UnsupportedType < StandardError; end + class InvalidConversion < StandardError; end + # == Setting + # + # There are two methods used to create a setting: + # 1. calling the class method <tt>setting</tt> from within an instance of ConfigureMe::Base + # 2. implicitly when a hash is fed to ConfigureMe::Base.load class Setting attr_reader :name, :type, :default - def initialize(owner, name, type, *args) + VALID_TYPES = [:string, :integer, :float, :boolean, :unknown] + TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'] + + def initialize(name, *args) options = args.extract_options! - @owner, @name, @type = owner, name.to_s, type + @name = name.to_s @default = options.key?(:default) ? options[:default] : nil + @type = options.key?(:type) ? options[:type] : infer_type(@default) + raise UnsupportedType.new("Invalid type: #{@type}") unless VALID_TYPES.include?(@type) end - def define_methods! - @owner.define_attribute_methods(true) - end - def convert(value) case type - when :string then value - when :text then value + when :string then convert_to_string(value) when :integer then value.to_i rescue value ? 1 : 0 - when :float then value.to_f - when :date then ActiveRecord::ConnectionAdapters::Column.string_to_date(value) - when :boolean then ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value) - else value + when :float then value.to_f rescue value ? 1.0 : 0.0 + when :boolean then convert_to_boolean(value) + when :unknown + @type = infer_type(value) + convert(value) + end + end + + private + + def infer_type(value) + case value + when String + :string + when Fixnum + :integer + when Float + :float + when TrueClass, FalseClass + :boolean + when NilClass + :unknown + else + raise InvalidDefault.new("Unable to infer type from #{value.inspect}") + end + end + + def convert_to_string(value) + case value + when String + value + when Fixnum, Float, TrueClass, FalseClass, NilClass + value.to_s + else + raise InvalidConversion.new("Unable to convert #{value.inspect} to string") + end + end + + def convert_to_boolean(value) + if value.is_a?(String) && value.blank? + nil + else + TRUE_VALUES.include?(value) end end end end