module CMDx::Validators::Numeric

def call(value, options = {})

def call(value, options = {})
  case options[:numeric]
  in { within: within }
    raise_within_validation_error!(within.begin, within.end, options) unless within.cover?(value)
  in { not_within: not_within }
    raise_not_within_validation_error!(not_within.begin, not_within.end, options) if not_within.cover?(value)
  in { in: yn }
    raise_within_validation_error!(yn.begin, yn.end, options) unless yn.cover?(value)
  in { not_in: not_in }
    raise_not_within_validation_error!(not_in.begin, not_in.end, options) if not_in.cover?(value)
  in { min: min, max: max }
    raise_within_validation_error!(min, max, options) unless value.between?(min, max)
  in { min: min }
    raise_min_validation_error!(min, options) unless min <= value
  in { max: max }
    raise_max_validation_error!(max, options) unless value <= max
  in { is: is }
    raise_is_validation_error!(is, options) unless value == is
  in { is_not: is_not }
    raise_is_not_validation_error!(is_not, options) if value == is_not
  else
    raise ArgumentError, "no known numeric validator options given"
  end
end

def raise_is_not_validation_error!(is_not, options)

def raise_is_not_validation_error!(is_not, options)
  message = options.dig(:numeric, :is_not_message) ||
            options.dig(:numeric, :message)
  message %= { is_not: } unless message.nil?
  raise ValidationError, message || I18n.t(
    "cmdx.validators.numeric.is_not",
    is_not:,
    default: "must not be #{is_not}"
  )
end

def raise_is_validation_error!(is, options)

def raise_is_validation_error!(is, options)
  message = options.dig(:numeric, :is_message) ||
            options.dig(:numeric, :message)
  message %= { is: } unless message.nil?
  raise ValidationError, message || I18n.t(
    "cmdx.validators.numeric.is",
    is:,
    default: "must be #{is}"
  )
end

def raise_max_validation_error!(max, options)

def raise_max_validation_error!(max, options)
  message = options.dig(:numeric, :max_message) ||
            options.dig(:numeric, :message)
  message %= { max: } unless message.nil?
  raise ValidationError, message || I18n.t(
    "cmdx.validators.numeric.max",
    max:,
    default: "must be at most #{max}"
  )
end

def raise_min_validation_error!(min, options)

def raise_min_validation_error!(min, options)
  message = options.dig(:numeric, :min_message) ||
            options.dig(:numeric, :message)
  message %= { min: } unless message.nil?
  raise ValidationError, message || I18n.t(
    "cmdx.validators.numeric.min",
    min:,
    default: "must be at least #{min}"
  )
end

def raise_not_within_validation_error!(min, max, options)

def raise_not_within_validation_error!(min, max, options)
  message = options.dig(:numeric, :not_within_message) ||
            options.dig(:numeric, :not_in_message) ||
            options.dig(:numeric, :message)
  message %= { min:, max: } unless message.nil?
  raise ValidationError, message || I18n.t(
    "cmdx.validators.numeric.not_within",
    min:,
    max:,
    default: "must not be within #{min} and #{max}"
  )
end

def raise_within_validation_error!(min, max, options)

def raise_within_validation_error!(min, max, options)
  message = options.dig(:numeric, :within_message) ||
            options.dig(:numeric, :in_message) ||
            options.dig(:numeric, :message)
  message %= { min:, max: } unless message.nil?
  raise ValidationError, message || I18n.t(
    "cmdx.validators.numeric.within",
    min:,
    max:,
    default: "must be within #{min} and #{max}"
  )
end