module DYI::Chart::OptionCreator

@private @since 1.0.0

Public Instance Methods

opt_accessor(name, settings = {}) click to toggle source

Difines a read-write property. @param [Symbol] name the property name @param [Hash] settings settings of the property

# File lib/dyi/chart/base.rb, line 186
def opt_accessor(name, settings = {})
  opt_reader(name, settings)
  opt_writer(name, settings)
end
opt_reader(name, settings = {}) click to toggle source

Difines a read property. @param [Symbol] name the property name @param [Hash] settings settings of the property

# File lib/dyi/chart/base.rb, line 33
def opt_reader(name, settings = {})
  name = name.to_sym
  getter_name = settings[:type] == :boolean ? name.to_s.gsub(/^(.*[^=\?])[=\?]*$/, '\1?') : name
  if settings.key?(:default)
    define_method(getter_name) {@options.key?(name) ? @options[name] : settings[:default]}
  elsif settings.key?(:default_method)
    define_method(getter_name) {@options.key?(name) ? @options[name] : __send__(settings[:default_method])}
  elsif settings.key?(:default_proc)
    define_method(getter_name) {@options.key?(name) ? @options[name] : settings[:default_proc].call(self)}
  else
    define_method(getter_name) {@options[name]}
  end
end
opt_writer(name, settings = {}) click to toggle source

Difines a write property. @param [Symbol] name the property name @param [Hash] settings settings of the property

# File lib/dyi/chart/base.rb, line 50
def opt_writer(name, settings = {})
  name = name.to_sym
  setter_name = name.to_s.gsub(/^(.*[^=\?])[=\?]*$/, '\1=')

  convertor =
    case settings[:type]
      when :boolen then proc {|value| not not value}
      when :string then proc {|value| value.to_s}
      when :symbol then proc {|value| value.to_sym}
      when :integer then proc {|value| value.to_i}
      when :float then proc {|value| value.to_f}
      when :length then proc {|value| Length.new(value)}
      when :point then proc {|value| Coordinate.new(value)}
      when :color then proc {|value| Color.new(value)}
      when :font then proc {|value| Font.new(value)}
      else proc {|value| value} if !settings.key?(:map_method) && !settings.key?(:mapper) && !settings.key?(:item_type)
    end

  validator =
    case settings[:type]
    when :symbol
      if settings.key?(:valid_values)
        proc {|value| raise ArgumentError, "\"#{value}\" is invalid value" unless settings[:valid_values].include?(convertor.call(value))}
      end
    when :integer, :float
      if settings.key?(:range)
        proc {|value| raise ArgumentError, "\"#{value}\" is invalid value" unless settings[:range].include?(convertor.call(value))}
      end
    end

  case settings[:type]
  when :hash
    raise ArgumentError, "keys is not specified" unless settings.key?(:keys)
    define_method(setter_name) {|values|
      if values.nil? || values.empty?
        @options.delete(name)
      else
        @options[name] =
          settings[:keys].inject({}) do |hash, key|
            hash[key] =
              if convertor
                convertor.call(values[key])
              elsif settings.key?(:map_method)
                __send__(settings[:map_method], values[key])
              elsif settings.key?(:mapper)
                settings[:mapper].call(values[key], self)
              elsif settings.key?(:item_type)
                case settings[:item_type]
                  when :boolen then not not values[key]
                  when :string then values[key].to_s
                  when :symbol then values[key].to_sym
                  when :integer then values[key].to_i
                  when :float then values[key].to_f
                  when :length then Length.new(values[key])
                  when :point then Coordinate.new(values[key])
                  when :color then value[key].respond_to?(:format) ? value[key] : Color.new(values[key])
                  when :font then Font.new(values[key])
                  else values[key]
                end
              end if values[key]
            hash
          end
      end
      values
    }
  when :array
    define_method(setter_name) {|values|
      if values.nil? || values.empty?
        @options.delete(name)
      else
        @options[name] =
          Array(values).to_a.map {|item|
            if convertor
              convertor.call(item)
            elsif settings.key?(:map_method)
              __send__(settings[:map_method], item)
            elsif settings.key?(:mapper)
              settings[:mapper].call(item, self)
            elsif settings.key?(:item_type)
              case settings[:item_type]
                when :boolen then not not item
                when :string then item.to_s
                when :symbol then item.to_sym
                when :integer then item.to_i
                when :float then item.to_f
                when :length then Length.new(item)
                when :point then Coordinate.new(item)
                when :color then item.respond_to?(:write_as) ? item : Color.new_or_nil(item)
                when :font then Font.new(item)
                else item
              end
            else
              item
            end
          }
      end
      values
    }
  else
    define_method(setter_name) {|value|
      if value.nil?
        @options.delete(name)
      else
        validator && validator.call(value)
        @options[name] =
          if convertor
            convertor.call(value)
          elsif settings.key?(:map_method)
            __send__(settings[:map_method], value)
          elsif ettings.key?(:mapper)
            settings[:mapper].call(value, self)
          elsif settings.key?(:item_type)
            case settings[:item_type]
              when :boolen then not not value
              when :string then value.to_s
              when :symbol then value.to_sym
              when :integer then value.to_i
              when :float then value.to_f
              when :length then Length.new(value)
              when :point then Coordinate.new(value)
              when :color then Color.new(value)
              when :font then Font.new(value)
              else value
            end
          else
            value
          end
      end
      value
    }
  end
end