# encoding: utf-8 module Policy # Policy object class interface # # Includes <tt>ActiveModel::Validation</tt> and a list of methods # to compose policies. module Base # Composes the policy with others by AND method # # @overload and(*others) # Returns a composition of the policy with other policies # # The composition is valid when all policies are valid. # # @example # composition = one_policy.and(another) # one_policy.valid? # => true # another.valid? # => false # composition.valid? # => false # # @param [Policy::Base, Array<Policy::Base>] others # other policies to compose the current policy with # # @return [Policy::Base] the composed policy # # @overload and() # Returns a negator object expecting negation of another policy # # @example # composition = one_policy.and.not(another) # one_policy.valid? # => true # another.valid? # => false # composition.valid? # => true # # @return [#not] def and(*others) compose And, others end # Composes the policy with others by OR method # # @overload or(*others) # Returns a composition of the policy with other policies # # The composition is valid when any policy is valid. # # @example # composition = one_policy.or(another) # one_policy.valid? # => true # another.valid? # => false # composition.valid? # => true # # @param [Policy::Base, Array<Policy::Base>] others # other policies to compose the current policy with # # @return [Policy::Base] the composed policy # # @overload or() # Returns a negator object expecting negation of another policy # # @example # composition = one_policy.or.not(another) # one_policy.valid? # => false # another.valid? # => false # composition.valid? # => true # # @return [#not] def or(*others) compose Or, others end # Composes the policy with others by XOR method # # @overload xor(another) # Returns a composition of the policy with other policies # # The composition is valid when both valid and invalid policies # are present # # @example # composition = one_policy.xor(another) # one_policy.valid? # => true # another.valid? # => true # composition.valid? # => false # # @param [Policy::Base, Array<Policy::Base>] others # other policies to compose the current policy with # # @return [Policy::Base] the composed policy # # @overload xor() # Returns a negator object expecting negation of another policy # # @example # composition = one_policy.xor.not(another) # one_policy.valid? # => false # another.valid? # => false # composition.valid? # => true # # @return [#not] def xor(*others) compose Xor, others end # @private def self.included(klass) klass.instance_eval { include ActiveModel::Validations } end private def compose(composer, policies) return composer.new(self, *policies) if policies.any? Negator.new(self, composer) end end # module Base end # module Policy