class AWS::Record::CountValidator

@api private

def interpolate message_with_placeholders, values

def interpolate message_with_placeholders, values
  msg = message_with_placeholders.dup
  values.each_pair do |key,value|
    msg.gsub!(/%\{#{key}\}/, value.to_s)
  end
  msg
end

def setup record_class

def setup record_class
  ensure_at_least_one(:within, :exactly, :minimum, :maximum)
  ensure_exclusive(:within, :exactly, [:minimum, :maximum])
  ensure_type(Range, :within)
  ensure_type(Integer, :exactly, :minimum, :maximum)
  ensure_type(String, :too_many, :too_few, :wrong_number)
end

def too_few min, got

def too_few min, got
  msg = options[:too_few] || "has too few values (minimum is %{minimum})"
  interpolate(msg, :minimum => min, :count => got)
end

def too_many max, got

def too_many max, got
  msg = options[:too_many] || "has too many values (maximum is %{maximum})"
  interpolate(msg, :maximum => max, :count => got)
end

def validate_attribute record, attribute_name, value

def validate_attribute record, attribute_name, value
  count = case value
  when nil then 0
  when String then 1
  when Enumerable then value.count
  else 1
  end
  if exact = options[:exactly]
    unless count == exact
      record.errors.add(attribute_name, wrong_number(exact, count))
    end
  end
  if within = options[:within]
    if count < within.first
      record.errors.add(attribute_name, too_few(within.first, count))
    end
    if count > within.last
      record.errors.add(attribute_name, too_many(within.last, count))
    end
  end
  if min = options[:minimum]
    if count < min
      record.errors.add(attribute_name, too_few(min, count))
    end
  end
  if max = options[:maximum]
    if count > max
      record.errors.add(attribute_name, too_many(max, count))
    end
  end
end

def wrong_number exactly, got

def wrong_number exactly, got
  msg = options[:wrong_number] ||
    "has the wrong number of values (should have %{exactly})"
  interpolate(msg, :exactly => exactly, :count => got)
end