class Attributor::HashDSLCompiler::Requirement
A class that encapsulates the definition of a requirement for Hash
attributes It implements the validation against incoming values and it describes its format for documentation purposes
Attributes
attr_names[R]
description[R]
number[R]
type[R]
Public Class Methods
new(description: nil, **spec)
click to toggle source
# File lib/attributor/hash_dsl_compiler.rb, line 13 def initialize(description: nil, **spec) @description = description @type = spec.keys.first case type when :all of(*spec[type]) when :exclusive of(*spec[type]) else @number = spec[type] end end
Public Instance Methods
describe(_shallow = false, _example: nil)
click to toggle source
# File lib/attributor/hash_dsl_compiler.rb, line 68 def describe(_shallow = false, _example: nil) hash = { type: type, attributes: attr_names } hash[:count] = number unless number.nil? hash[:description] = description unless description.nil? hash end
of(*args)
click to toggle source
# File lib/attributor/hash_dsl_compiler.rb, line 26 def of(*args) @attr_names = args self end
validate(keys, context = Attributor::DEFAULT_ROOT_CONTEXT, _attribute = nil)
click to toggle source
# File lib/attributor/hash_dsl_compiler.rb, line 31 def validate(keys, context = Attributor::DEFAULT_ROOT_CONTEXT, _attribute = nil) result = [] case type when :all rest = attr_names - keys unless rest.empty? rest.each do |attr| sub_context = Attributor::Hash.generate_subcontext(context, attr) result.push "Attribute #{Attributor.humanize_context(sub_context)} is required." end end when :exactly included = attr_names & keys unless included.size == number result.push "Exactly #{number} of the following attributes #{attr_names} are required for #{Attributor.humanize_context(context)}. Found #{included.size} instead: #{included.inspect}" end when :at_most rest = attr_names & keys if rest.size > number found = rest.empty? ? 'none' : rest.inspect result.push "At most #{number} attributes out of #{attr_names} can be passed in for #{Attributor.humanize_context(context)}. Found #{found}" end when :at_least rest = attr_names & keys if rest.size < number found = rest.empty? ? 'none' : rest.inspect result.push "At least #{number} attributes out of #{attr_names} are required to be passed in for #{Attributor.humanize_context(context)}. Found #{found}" end when :exclusive intersection = attr_names & keys if intersection.size > 1 result.push "Attributes #{intersection.inspect} are mutually exclusive for #{Attributor.humanize_context(context)}." end end result end