# encoding: utf-8 module Policy module Follower # Collection of policy names to be followed # # @api private class Policies include Enumerable # @!scope class # @!method new(follower) # Creates the empty collection for the follower class # # @param [Class] follower # # @return [Policy::Follower::Policies] the collection object def initialize(follower) @follower = follower @names = [] end # Adds the policy name to the list of followed policies # # @example # Policies.new.add("some_policy") # # @param [#to_sym] policy # # @return [self] itself def add(policy) name = policy.to_sym names << name unless names.include? name self end # Checks whether the name is included to the {#names} # # @param [Symbol] name # # @raise [Policy::Followers::NameError] if the name not registered yet # # @return [true] def include?(name) fail(NameError.new(follower, name)) unless names.include?(name) true end # Returns the subset of current collection # # @overload subset() # @return [self] itself # # @overload subset(*names) # @example # policies = Policies.new(follower, %i(foo bar baz)) # policies.subset(:baz, :foo) # # => # # # @param [Symbol, Array] names # # @raise [Policy::Follower::NameError] # if subset contains unregistered policies # # @return [Policy::Follower::Policies] def subset(*names) return self unless names.flatten.any? policies = self.class.new(follower) valid(names).each(&policies.method(:add)) policies end # Iterates through names of the policies # # @return [Enumerator] # # @yieldparam [Symbol] the name of the registered policy def each return to_enum unless block_given? names.each { |name| yield(name) } end # @!attribute [r] follower # The class that follows policies # # @return [Class] attr_reader :follower private attr_reader :names def valid(names) names.flatten.map(&:to_sym).select(&method(:include?)) end end # class Policies end # module Follower end # module Policy