Argx (Argx v1.1.4)

Check args using configs.

Example

This Example Project is the basis for Argx, help you use well. Download via Gitee or Github.

Quick Start

Here’s a commented example.

# Use Argx like this in Your Project.
iex> defmodule YourProject do
...>   # step 1: introduce check function by Argx module
...>   use Argx
...>
...>   # step 2: define rule
...>   defconfig(Rule, id(:string))
...>
...>   def get(args) do
...>     # step 3: use check function to check args
...>     check(args, [Rule])
...>   end
...> end

# Return errors.
iex> YourProject.get(%{id: 1})
{:error, ["error type: id"]}

# If passed, return original args.
iex> YourProject.get(id: "a")
[id: "a"]

Check Via DSL

# step 1: define your validator
defmodule YourProject.Validator do
  use Argx.WithCheck
end

defmodule YourProject do
  # step 2: import your validator
  import YourProject.Validator

  # step 3: use with_check macro to wrap your function(s)
  with_check configs(id(:string)) do
    def get(id) do
      {id}
    end
  end
end

Advanced

1. How to share arg configs?

step 1: create a module for define shared arg configs.

defmodule YourProject.ArgConfigs do
  use Argx.Defconfig
  defconfig(NumberRule, number(:string, :empty))
  defconfig(PageSizeRule, page_size(:integer, :autoconvert, 1..100) || 10)
end

step 2 : config share module to the following positions.

use Argx, share: YourProject.ArgConfigs
# or
use Argx.WithCheck, share: YourProject.ArgConfigs

step 3 : use arg config by name.

def get(args) do
  check(args, [NumberRule, PageSizeRule])
  |> case do
    {:error, _} -> :error
    _ -> :ok
  end
end
# or
with_check configs(NumberRule, PageSizeRule) do
  def get(id) do
    {id}
  end
end

2. Format errors

just implement callback fmt_errors/1, Argx invoke your custom format errors function, when check done.

There are 3 places to put it.

Highest priority: in the current module.

defmodule YourProject do
  use Argx
  def fmt_errors({:error, _errors}), do: :error
  def fmt_errors(_new_args_or_result), do: :ok
  ...
end
# or
defmodule YourProject do
  import YourProject.Validator
  def fmt_errors({:error, _errors}), do: :error
  def fmt_errors(_new_args_or_result), do: :ok
  ...
end

Second priority: in the share arg configs module.

defmodule YourProject.ArgConfigs do
  use Argx.Defconfig
  def fmt_errors({:error, _errors}), do: :error
  def fmt_errors(_new_args_or_result), do: :ok
  ...
end

Lowest priority: if you use argx via with_check, also implement it in the definition module.

defmodule YourProject.Validator do
  use Argx.WithCheck
  def fmt_errors({:error, _errors}), do: :error
  def fmt_errors(_new_args_or_result), do: :ok
  ...
end

Features

  • set default value if arg is nil or empty.
  • convert arg's value automatically, if arg's value is compatible, such as: "1" to 1.
  • check whether arg is lacked or empty.
  • check whether arg's type is error.
  • check whether arg's length/value is out of range.
  • support nested data checking.
  • similar checkbox functionality, required at least one arg is not nil in group.
  • similar radio functionality, required only one arg is not nil in group.

Support Data Type

  • :boolean
  • :integer
  • :float
  • :string
  • :list
  • :map

check/2 function

  • meaning of function's arg:
    • first arg only accept map or keyword data type as checking args.
    • second arg must be a list that only contains one or more rule names.
      check(data, [RuleA, :RuleB, "RuleC"])
  • return value:
    • return new args, if success.
    • return errors, if failure.

Errors

There are 3 types.

  1. lacked some fields.
  2. some fields' type is error.
  3. some field's range/length/size is out of range.
  4. checkbox functionality error.
  5. radio functionality error.

As shown below:

{
  :error,
  [
    error_type: ["cargoes:1:number", "cargoes:2:name"], # report nested data's error
    lacked: [:mobile],
    out_of_range: [:weight],
    checkbox_error: [:id, :number],
    radio_error: [:ip, :addr]
  ]
}

If you want to convert meta errors to readable message, just implement fmt_errors/1.

Configuration

config Argx or Argx.WithCheck module.

  1. set shared arg configs module.
  2. set warn flag.
    use Argx, share: YourProject.ArgConfigs, warn: false

Benchmark

mix bench
## ArgxBench
benchmark name                  iterations   average time
deep match (4 nested level)     50000        44.65 µs/op