saturnflyer/surrounded

View on GitHub
lib/surrounded/context/role_map.rb

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
require "triad"
require "forwardable"
module Surrounded
  module Context
    class RoleMap
      extend Forwardable

      class << self
        # Get the role map container and provide an alternative if desired
        # Ex: RoleMap.from_base(SomeCustomContainer)
        def from_base(klass = ::Triad)
          unless const_defined?(:Container)
            role_mapper = Class.new(self)
            role_mapper.container_class = (klass)
            Surrounded::Exceptions.define(role_mapper, exceptions: :ItemNotPresent, namespace: klass)
            const_set(:Container, role_mapper)
          end
          const_get(:Container)
        end

        attr_writer :container_class
      end

      def_delegators :container, :update, :each, :values, :keys

      def container
        @container ||= self.class.instance_variable_get(:@container_class).new
      end

      # Check if a role exists in the map
      def role?(role)
        keys.include?(role)
      end

      # Check if an object is playing a role in this map
      def role_player?(object)
        !values(object).empty?
      rescue container.class::ItemNotPresent
        false
      end

      # Get the object playing the given role
      def assigned_player(role)
        values(role).first
      end
    end
  end
end