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"
to1
. - 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.
- lacked some fields.
- some fields' type is error.
- some field's range/length/size is out of range.
- checkbox functionality error.
- 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.
- set shared arg configs module.
- 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