Sha256: ff2dc02f3cfe1a27b7265637086ff24e5aa389c1f16a707e0c70c2ba01250d91

Contents?: true

Size: 1.65 KB

Versions: 9

Compression:

Stored size: 1.65 KB

Contents

# encoding: utf-8
module EnumField
  class Builder
    def initialize(target)
      @target = target
      @next_id = 0
      @id2obj = {}
      @name2obj = {}
      @sorted = []
    end

    def member(name, options = {})
      obj, candidate_id = process_options(options)
      assign_id(obj, candidate_id)
      define_in_meta(name) { obj }
      save(name, obj)
      obj.freeze
    end

    def all
      @sorted.dup
    end

    def names
      @name2obj.keys
    end

    def find(id)
      find_by_id(id) or raise EnumField::ObjectNotFound
    end

    def find_by_id(id)
      @id2obj[id.to_i]
    end

    def first; @sorted.first; end
    def last; @sorted.last; end

    private

    def define_in_meta(name, &block)
      metaclass = class << @target; self; end
      metaclass.send(:define_method, name, &block)
    end

    def assign_id(obj, candidate_id)
      id = new_id(candidate_id)
      obj.instance_variable_set(:@id, id)
    end

    def new_id(candidate)
      validate_candidate_id(candidate)
      candidate || find_next_id
    end

    def validate_candidate_id(id)
      raise EnumField::InvalidId.new(id) unless id.nil? || id.is_a?(Integer) && id > 0
      raise EnumField::RepeatedId.new(id) if @id2obj.has_key?(id)
    end

    def find_next_id
      @next_id += 1 while @id2obj.has_key?(@next_id) || @next_id <= 0
      @next_id
    end

    def process_options(options)
      raise EnumField::InvalidOptions unless options.reject {|k,v| k == :object || k == :id}.empty?
      [options[:object] || @target.new, options[:id]]
    end

    def save(name, obj)
      @id2obj[obj.id] = obj
      @sorted << obj
      @name2obj[name] = obj
    end
  end
end

Version data entries

9 entries across 9 versions & 2 rubygems

Version Path
galetahub-enum_field-0.2.2 lib/enum_field/builder.rb
galetahub-enum_field-0.2.1 lib/enum_field/builder.rb
sunrise-cms-0.5.0.rc1 vendor/bundle/ruby/1.9.1/gems/galetahub-enum_field-0.2.0/lib/enum_field/builder.rb
sunrise-cms-0.3.3 vendor/bundle/ruby/1.9.1/gems/galetahub-enum_field-0.2.0/lib/enum_field/builder.rb
sunrise-cms-0.3.2 vendor/bundle/ruby/1.9.1/gems/galetahub-enum_field-0.2.0/lib/enum_field/builder.rb
sunrise-cms-0.3.1 vendor/bundle/ruby/1.9.1/gems/galetahub-enum_field-0.2.0/lib/enum_field/builder.rb
sunrise-cms-0.3.0 vendor/bundle/ruby/1.9.1/gems/galetahub-enum_field-0.2.0/lib/enum_field/builder.rb
sunrise-cms-0.3.0.rc vendor/bundle/ruby/1.9.1/gems/galetahub-enum_field-0.2.0/lib/enum_field/builder.rb
galetahub-enum_field-0.2.0 lib/enum_field/builder.rb