Sha256: 35ddcf866fdde8d5271d5436e5dd5171a5997d2c635138a2a41408fe38cf1ea4

Contents?: true

Size: 1.49 KB

Versions: 1

Compression:

Stored size: 1.49 KB

Contents

# frozen_string_literal: true

class ActWithFlags::Admin
  Location = Struct.new(:model, :origin, :position)

  attr_reader :locations

  def mask(*flags)
    return 0 if flags.empty?

    res = mask2d(*flags)
    raise "Mixing origins fails: #{flags}" unless res.length == 1

    res.values.first
  end

  def mask2d(*flags)
    res = {}
    flags.each { |flag|
      model, orig, pos = location(flag).values
      idx = "#{model}##{orig}"
      mask = res[idx] || 0
      res[idx] = mask | (1 << pos)
    }
    res
  end

  def location(name)
    location = @locations[name]
    return location if location

    parent = model.superclass.act_with_flags
    return parent.location(name) if parent

    raise "unknown flag '#{model}##{name}'"
  end

  private

  def position(name)
    location(name).position
  end

  def add_to_locations(flag, location)
    location = check_position(location)
    who = "<#{flag}: #{location.origin}@#{location.position}>"
    raise "name already used #{who}" if @locations.key?(flag)
    bool = @locations.has_value?(location)
    raise "position already used #{who}" if bool
    @locations[flag] = location
  end

  def check_position(location)
    model, orig, pos = location.values
    return location if pos

    max_position = -1
    @locations.each { |name, location|
      model2, orig2, pos2 = location.values
      next unless model == model2 && orig == orig2

      max_position = pos2 if pos2 > max_position
    }

    Location.new(model, orig, max_position + 1)
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
act_with_flags-3.0.1 lib/act_with_flags/flags.rb