valdi
valdi copied to clipboard
Simple data validation for elixir
Valdi
Data validation for Elixir
Installation
The package can be installed by adding valdi
to your list of dependencies in mix.exs
:
def deps do
[
{:valdi, "~> 0.5.0"}
]
end
Document can be found at https://hexdocs.pm/valdi.
Features
Some helpers function to do validate data
- Validate type
- validate inclusion/exclusion
- validate length for string and enumerable types
- validate number
- validate string format/pattern
- validate custom function
- validate required(not nil) or not
- validate decimal (thanks @madclaws)
Usage
- Each of these validations can be used separatedly
iex(2)> Valdi.validate_type(10, :integer)
:ok
iex(3)> Valdi.validate_type(10, :string)
{:error, "is not a string"}
iex(3)> Valdi.validate_number(9, [min: 10, max: 20])
{:error, "must be greater than or equal to 10"}
- Or you can combine multiple condition at one
iex(12)> Valdi.validate(10, type: :integer, number: [min: 10, max: 20])
:ok
iex(13)> Valdi.validate("[email protected]", type: :string, format: ~r/.+@.+\.[a-z]{2,10}/)
{:error, "format not matched"}
- You can validate list of value
iex(51)> Valdi.validate_list([1,2,3], type: :integer, number: [min: 2])
{:error, [[0, "must be greater than or equal to 2"]]}
- And validate map data too
iex(54)> validation_spec = %{
...(54)> email: [type: :string],
...(54)> password: [type: :string, length: [min: 8]],
...(54)> age: [type: :integer, number: [min: 16, max: 60]]
...(54)> }
iex(56)> Valdi.validate_map(%{name: "dzung", password: "123456", emal: "[email protected]", age: 28}, validation_spec)
{:error, %{password: "length must be greater than or equal to 8"}}
Supported validations
Type validation for built-in types and collection:
-
:boolean
-
:integer
-
:float
-
:number
(int or float) -
:string
,:binary
(string is binary alias) -
:tuple
-
:array
,:list
-
:atom
-
:function
-
:map
-
:date
-
:time
-
:datetime
-
:naive_datetime
-
:utc_datetime
-
{:array, type}
array of item similar to Ecto.Schema -
:keyword
-
struct
for example:User
. it's the struct module name
iex(11)> Valdi.validate(["one", "two", "three"], type: {:array, :string})
:ok
iex(12)> Valdi.validate(["one", "two", "three"], type: :array)
:ok
iex(13)> Valdi.validate(["one", "two", "three"], type: :map)
{:error, "is not a map"}
iex(14)>
Validate required Validate value if value is not nil. This function can receive a function to dynamicall calculate required or not.
iex(1)> Magik.Validator.validate_required(nil, true)
{:error, "is required"}
iex(2)> Magik.Validator.validate_required(1, true)
:ok
iex(3)> Magik.Validator.validate_required(nil, false)
:ok
iex(4)> Magik.Validator.validate_required(nil, fn -> 2 == 2 end)
{:error, "is required"}
Validate inclusion and exclusion
iex(15)> Valdi.validate("one", in: ~w(one two three))
:ok
iex(16)> Valdi.validate("five", in: ~w(one two three))
{:error, "not be in the inclusion list"}
iex(17)> Valdi.validate("five", not_in: ~w(one two three))
:ok
Validate format/regex
iex(13)> Valdi.validate("[email protected]", type: :string, format: ~r/.+@.+\.[a-z]{2,10}/)
{:error, "format not matched"}
iex(18)> Valdi.validate("123", format: ~r/\d{3}/)
:ok
Validate number
Here are list of check condition on number value:
-
equal_to
-
greater_than_or_equal_to
|min
-
greater_than
-
less_than
-
less_than_or_equal_to
|max
iex(19)> Valdi.validate(12, number: [greater_than: 0, less_than: 20])
:ok
iex(20)> Valdi.validate(12, number: [min: 0, max: 10])
{:error, "must be less than or equal to 10"}
iex(21)> Valdi.validate(12, number: [equal_to: 10])
{:error, "must be equal to 10"}
iex(22)>
Validate decimal Similar to validate number
iex(19)> Valdi.validate(Decimal.new("10.0"), decimal: [greater_than: Decimal.new("0.0"), less_than: Decimal.new("20.0")])
:ok
Validate string and enumerable length
Valdi supported check length for map
, list
, binary
, tuple
All check conditions are the same with number validation
iex(24)> Valdi.validate("mypassword", length: [min: 8, max: 16])
:ok
iex(25)> Valdi.validate([1, 2, 3], length: [min: 3])
:ok
iex(26)> Valdi.validate({"one", "two"}, length: [min: 3])
{:error, "length must be greater than or equal to 3"}
iex(27)> Valdi.validate(50, length: [min: 2])
{:error, "length check supports only lists, binaries, maps and tuples"}
Custom validation function
You can pass your validation function too. You function must follow spec:
func(any()):: :ok | {:error, message::String.t()}
iex(32)> Valdi.validate(12, func: fn val -> if is_binary(val), do: :ok, else: {:error, "not a string"} end)
{:error, "not a string"}
Validate each array element Support all above validator to validate each array element
iex(32)> Valdi.validate([1, 10, 20], each: [number: [min: 10]])
{:error, [[0, "must be greater than or equal to 10"]]}