Packages
zoi
0.14.1
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.1
0.16.0
0.15.0
0.14.1
0.14.0
0.13.1
0.13.0
0.12.1
0.12.0
0.11.1
0.11.0
0.10.7
0.10.6
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.1
0.9.0
0.9.0-rc.1
0.9.0-rc.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.0
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.3
0.1.2
0.1.1
0.1.0
Zoi is a schema validation library for Elixir, designed to provide a simple and flexible way to define and validate data.
Current section
Files
Jump to
Current section
Files
lib/zoi/types/time.ex
defmodule Zoi.Types.Time do
@moduledoc false
use Zoi.Type.Def, fields: [:gte, :lte, :gt, :lt, coerce: false]
alias Zoi.Validations
def opts() do
error = "invalid type: expected time"
Zoi.Opts.meta_opts()
|> Zoi.Opts.with_coerce()
|> Zoi.Types.Extend.new(
gte:
Zoi.Opts.constraint_schema(Zoi.Types.Time.new([]),
description: "time minimum value",
error: error
),
lte:
Zoi.Opts.constraint_schema(Zoi.Types.Time.new([]),
description: "time maximum value",
error: error
),
gt:
Zoi.Opts.constraint_schema(Zoi.Types.Time.new([]),
description: "time greater than value",
error: error
),
lt:
Zoi.Opts.constraint_schema(Zoi.Types.Time.new([]),
description: "time less than value",
error: error
)
)
end
def new(opts \\ []) do
{validation_opts, opts} = Keyword.split(opts, [:gte, :lte, :gt, :lt])
opts
|> apply_type()
|> Validations.maybe_set_validation(Validations.Gte, validation_opts[:gte])
|> Validations.maybe_set_validation(Validations.Lte, validation_opts[:lte])
|> Validations.maybe_set_validation(Validations.Gt, validation_opts[:gt])
|> Validations.maybe_set_validation(Validations.Lt, validation_opts[:lt])
end
defimpl Zoi.Type do
def parse(schema, %Time{} = input, _opts) do
case validate_constraints(schema, input) do
:ok -> {:ok, input}
{:error, errors} -> {:error, errors}
end
end
def parse(schema, input, opts) do
coerce = Keyword.get(opts, :coerce, schema.coerce)
with {:ok, parsed} <- maybe_coerce(coerce, schema, input),
:ok <- validate_constraints(schema, parsed) do
{:ok, parsed}
end
end
defp maybe_coerce(true, schema, input), do: coerce(schema, input)
defp maybe_coerce(_false, schema, _input), do: error(schema)
defp coerce(schema, input) when is_binary(input) do
case Time.from_iso8601(input) do
{:error, _reason} ->
error(schema)
{:ok, parsed} ->
{:ok, parsed}
end
end
defp coerce(schema, _input) do
error(schema)
end
defp error(schema) do
{:error, Zoi.Error.invalid_type(:time, error: schema.meta.error)}
end
defp validate_constraints(schema, input) do
[
{Validations.Gte, schema.gte},
{Validations.Lte, schema.lte},
{Validations.Gt, schema.gt},
{Validations.Lt, schema.lt}
]
|> Validations.run_validations(schema, input)
end
end
defimpl Zoi.TypeSpec do
def spec(_schema, _opts) do
quote(do: Time.t())
end
end
defimpl Zoi.Validations.Gte do
def set(schema, value, opts \\ []) do
%{schema | gte: {value, opts}}
end
def validate(_schema, input, value, opts) do
case Time.compare(input, value) do
:gt -> :ok
:eq -> :ok
:lt -> {:error, Zoi.Error.greater_than_or_equal_to(:date, value, opts)}
end
end
end
defimpl Zoi.Validations.Lte do
def set(schema, value, opts \\ []) do
%{schema | lte: {value, opts}}
end
def validate(_schema, input, value, opts) do
case Time.compare(input, value) do
:lt -> :ok
:eq -> :ok
:gt -> {:error, Zoi.Error.less_than_or_equal_to(:date, value, opts)}
end
end
end
defimpl Zoi.Validations.Gt do
def set(schema, value, opts \\ []) do
%{schema | gt: {value, opts}}
end
def validate(_schema, input, value, opts) do
case Time.compare(input, value) do
:gt -> :ok
_ -> {:error, Zoi.Error.greater_than(:date, value, opts)}
end
end
end
defimpl Zoi.Validations.Lt do
def set(schema, value, opts \\ []) do
%{schema | lt: {value, opts}}
end
def validate(_schema, input, value, opts) do
case Time.compare(input, value) do
:lt -> :ok
_ -> {:error, Zoi.Error.less_than(:date, value, opts)}
end
end
end
defimpl Inspect do
alias Zoi.Validations
def inspect(type, opts) do
extra_fields = [
gte: Validations.unwrap_validation(type.gte),
lte: Validations.unwrap_validation(type.lte),
gt: Validations.unwrap_validation(type.gt),
lt: Validations.unwrap_validation(type.lt)
]
Zoi.Inspect.build(type, opts, extra_fields)
end
end
defimpl Zoi.JSONSchema.Encoder do
def encode(schema) do
%{type: :string, format: :time}
|> maybe_add(:minimum, schema.gte)
|> maybe_add(:maximum, schema.lte)
|> maybe_add(:exclusiveMinimum, schema.gt)
|> maybe_add(:exclusiveMaximum, schema.lt)
end
defp maybe_add(map, _key, nil), do: map
defp maybe_add(map, key, {value, _opts}), do: Map.put(map, key, Time.to_iso8601(value))
end
defimpl Zoi.Describe.Encoder do
def encode(_schema), do: "`t:Time.t/0`"
end
end