View Source Peri (peri v0.2.2)
Peri is a schema validation library for Elixir, inspired by Clojure's Plumatic Schema. It focuses on validating raw maps and supports nested schemas and optional fields.
Usage
To define a schema, use the defschema
macro. By default, all fields in the schema are optional unless specified as {:required, type}
.
defmodule MySchemas do
import Peri
defschema :user, %{
name: :string,
age: :integer,
email: {:required, :string},
address: %{
street: :string,
city: :string
},
tags: {:list, :string},
role: {:enum, [:admin, :user, :guest]},
geolocation: {:tuple, [:float, :float]},
rating: {:custom, &validate_rating/1}
}
defp validate_rating(n) when n < 10, do: :ok
defp validate_rating(_), do: {:error, "invalid rating", []}
end
You can then use the schema to validate data:
user_data = %{name: "John", age: 30, email: "john@example.com", address: %{street: "123 Main St", city: "Somewhere"}, tags: ["science", "funky"], role: :admin, geolocation: {12.2, 34.2}, rating: 9}
case MySchemas.user(user_data) do
{:ok, valid_data} -> IO.puts("Data is valid!")
{:error, errors} -> IO.inspect(errors, label: "Validation errors")
end
Available Types
:string
- Validates that the field is a binary (string).:integer
- Validates that the field is an integer.:float
- Validates that the field is a float.:boolean
- Validates that the field is a boolean.:atom
- Validates that the field is an atom.:any
- Allow any datatype.{:required, type}
- Marks the field as required and validates it according to the specified type.:map
- Validates that the field is a map without checking nested schema.{:either, {type_1, type_2}}
- Validates that the field is either oftype_1
ortype_2
.{:oneof, types}
- Validates that the field is at least one of the provided types.{:list, type}
- Validates that the field is a list where elements belongs to a determined type.{:tuple, types}
- Validates that the field is a tuple with determined size and each element have your own type validation (sequential).{custom, anonymous_fun_arity_1}
- Validates that the field passes on the callback, the function needs to return either:ok
or{:error, reason}
wherereason
should be a string.{:custom, {MyModule, :my_validation}}
- Same as{custom, anonymous_fun_arity_1}
but you pass a remote module and a function name as atom.{:custom, {MyModule, :my_validation, [arg1, arg2]}}
- Same as{:custom, {MyModule, :my_validation}}
but you can pass extra arguments to your validation function. Note that the value of the field is always the first argument.
Summary
Functions
Defines a schema with a given name and schema definition.
Validates a given data map against a schema.
Functions
Defines a schema with a given name and schema definition.
Examples
defmodule MySchemas do
import Peri
defschema :user, %{
name: :string,
age: :integer,
email: {:required, :string}
}
end
user_data = %{name: "John", age: 30, email: "john@example.com"}
MySchemas.user(user_data)
# => {:ok, %{name: "John", age: 30, email: "john@example.com"}}
invalid_data = %{name: "John", age: 30}
MySchemas.user(invalid_data)
# => {:error, [email: "is required"]}
Validates a given data map against a schema.
Returns {:ok, data}
if the data is valid according to the schema, or {:error, errors}
if there are validation errors.
Parameters
- schema: The schema definition map.
- data: The data map to be validated.
Examples
schema = %{
name: :string,
age: :integer,
email: {:required, :string}
}
data = %{name: "John", age: 30, email: "john@example.com"}
Peri.validate(schema, data)
# => {:ok, %{name: "John", age: 30, email: "john@example.com"}}
invalid_data = %{name: "John", age: 30}
Peri.validate(schema, invalid_data)
# => {:error, [email: "is required"]}