defmodule Gulib.Validations.Length do def validate(value, options \\ []) do Gulib.Validate.unless_skipping(value, options) do size = Gulib.String.length(value, trim: (Keyword.get(options, :trim))) case bounds(options) do {nil, nil} -> raise "Missing length validation range(is, min, max or range)" {same, same} -> if size == same do :ok else {:fail, :wrong_length, Gulib.Translator.dgettext("validate", "must have a length of %{length}", length: same)} end {nil, max} -> if size <= max do :ok else {:fail, :too_long, Gulib.Translator.dgettext("validate", "must have a length of no more than %{max}", max: max)} end {min, nil} -> if min <= size do :ok else {:fail, :too_short, Gulib.Translator.dgettext("validate", "must have a length of at least %{min}", min: min)} end {min, max} -> if min <= size and size <= max do :ok else {:fail, :wrong_length, Gulib.Translator.dgettext("validate", "must have a length between %{min} and %{max}", min: min, max: max)} end end end end defp bounds(options) do is = Keyword.get(options, :is) min = Keyword.get(options, :min) max = Keyword.get(options, :max) range = Keyword.get(options, :in) cond do is -> {is, is} min -> {min, max} max -> {min, max} range -> {range.first, range.last} true -> {nil, nil} end end end