lib/validators/inclusion.ex

defmodule Dsv.Inclusion do
  use Dsv.Validator

  @moduledoc """

  Check if the given value is on the list of possible values.
  Dsv.Inclusion module provides a function to determine if a value is present in a list.

  """

  message("Value <%= inspect data %> must be one of the <%= inspect options %>")

  @doc """

  The `valid?/2` function evaluates whether a given value is present in a provided list.

  ## Parameters

    * `value` - The value to be checked.
    * `list` - The list in which the presence of the value is checked.

  ## Returns

  A boolean value:

  - `true` if `value` is present in `list`.
  - `false` if `value` is not present in `list`.

  ## Examples

      iex> Dsv.Inclusion.valid?("test", ["a", :b, "c", %{a: :b}])
      :false

      iex> Dsv.Inclusion.valid?("test", ["test", :b, "c", %{a: :b}])
      :true

      iex> Dsv.Inclusion.valid?(%{a: :b}, ["test", :b, "c", %{a: :b}])
      :true

      iex> Dsv.Inclusion.valid?(%{a: :b}, ["test", :b, "c", %{a: :b, c: :d}])
      :false

      iex> Dsv.Inclusion.valid?("test", [])
      :false

      iex> Dsv.Inclusion.valid?(nil, [nil, 1, 2, 3])
      :true

      iex> Dsv.Inclusion.valid?(nil, [1, 2, 3])
      :false

  """
  def valid?(data, options: options), do: valid?(data, options)
  def valid?(data, options) when is_list(options), do: data in options

  @doc """

  The `validate/2` function evaluates whether a given value is present in a provided list.

  ## Parameters

    * `value` - The value to be checked.
    * `list` - The list in which the presence of the value is checked.

  ## Returns

  - `:ok` if `value` is present in `list`.
  - `{:error, message}` if `value` is not present in `list`.

  ## Examples

      iex> Dsv.Inclusion.validate("test", ["a", :b, "c", %{a: :b}])
      {:error, ~s(Value "test" must be one of the ["a", :b, "c", %{a: :b}])}

      iex> Dsv.Inclusion.validate("test", ["test", :b, "c", %{a: :b}])
      :ok

      iex> Dsv.Inclusion.validate(%{a: :b}, ["test", :b, "c", %{a: :b}])
      :ok

      iex> Dsv.Inclusion.validate(%{a: :b}, ["test", :b, "c", %{a: :b, c: :d}])
      {:error, ~s(Value %{a: :b} must be one of the ["test", :b, "c", %{a: :b, c: :d}])}

      iex> Dsv.Inclusion.validate("test", [])
      {:error, ~s(Value "test" must be one of the [])}

      iex> Dsv.Inclusion.validate(nil, [nil, 1, 2, 3])
      :ok

      iex> Dsv.Inclusion.validate(nil, [1, 2, 3])
      {:error, ~s(Value nil must be one of the [1, 2, 3])}
  """
  def validate(data, options), do: super(data, options)

  @doc """

  The `validate/3` function evaluates whether a given value is present in a provided list.

  ## Parameters

    * `value` - The value to be checked.
    * `list` - The list in which the presence of the value is checked.
    * `message` - Custom message that will be returned in case of failure.

  ## Returns

  - `:ok` if `value` is present in `list`.
  - `{:error, message}` if `value` is not present in `list`.

  ## Examples

      iex> Dsv.Inclusion.validate("test", ["a", :b, "c", %{a: :b}], "Provided value is not accepted.")
      {:error, "Provided value is not accepted."}

      iex> Dsv.Inclusion.validate("test", ["test", :b, "c", %{a: :b}], "Provided value is not accepted.")
      :ok

      iex> Dsv.Inclusion.validate(%{a: :b}, ["test", :b, "c", %{a: :b}], "Provided value is not accepted.")
      :ok

      iex> Dsv.Inclusion.validate(%{a: :b}, ["test", :b, "c", %{a: :b, c: :d}], "Provided value is not accepted.")
      {:error, "Provided value is not accepted."}

      iex> Dsv.Inclusion.validate("test", [], "Provided value is not accepted.")
      {:error, "Provided value is not accepted."}

      iex> Dsv.Inclusion.validate(nil, [nil, 1, 2, 3], "Provided value is not accepted.")
      :ok

      iex> Dsv.Inclusion.validate(nil, [1, 2, 3], "Provided value is not accepted.")
      {:error, "Provided value is not accepted."}

  """
  def validate(data, options, message), do: validate(data, options: options, message: message)
end