defmodule Fussy.Validators.Either do
@behaviour Fussy.Validator
alias Fussy.Utils
defstruct [:variants]
@opaque t :: %__MODULE__{}
@spec new(list(Fussy.Validator.t())) :: __MODULE__.t()
def new([]), do: raise(ArgumentError, "must provide at least one variant")
def new(variants) when is_list(variants) do
struct!(%__MODULE__{}, variants: variants)
end
@impl true
def validate(%__MODULE__{variants: variants}, term) do
variants
|> Enum.find_value(
{:error, ["must be one of the defined variants"]},
fn variant ->
case Utils.validate_using(variant, term) do
{:ok, valid_term} ->
{:ok, valid_term}
{:error, _} ->
nil
end
end
)
end
end