Packages
zoi
0.11.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/float.ex
defmodule Zoi.Types.Float do
@moduledoc false
use Zoi.Type.Def, fields: [:gte, :lte, :gt, :lt, coerce: false]
alias Zoi.Validations
def opts() do
error = "invalid type: expected number"
Zoi.Opts.meta_opts()
|> Zoi.Opts.with_coerce()
|> Zoi.Types.Extend.new(
gte:
Zoi.Opts.constraint_schema(Zoi.Types.Number.new([]),
description: "float greater than or equal to",
error: error
),
lte:
Zoi.Opts.constraint_schema(Zoi.Types.Number.new([]),
description: "float less than or equal to",
error: error
),
gt:
Zoi.Opts.constraint_schema(Zoi.Types.Number.new([]),
description: "float greater than",
error: error
),
lt:
Zoi.Opts.constraint_schema(Zoi.Types.Number.new([]),
description: "float less than",
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, input, opts) do
coerce = Keyword.get(opts, :coerce, schema.coerce)
with {:ok, parsed} <- parse_type(input, coerce, schema),
:ok <- validate_constraints(schema, parsed) do
{:ok, parsed}
end
end
defp parse_type(input, _coerce, _schema) when is_float(input), do: {:ok, input}
defp parse_type(input, true, schema) when is_binary(input) do
case Float.parse(input) do
{float, ""} -> {:ok, float}
_error -> error(schema)
end
end
defp parse_type(_input, _coerce, schema), do: error(schema)
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
defp error(schema) do
{:error, Zoi.Error.invalid_type(:float, error: schema.meta.error)}
end
def type_spec(_schema, _opts) do
quote(do: float())
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
if input >= value do
:ok
else
{:error, Zoi.Error.greater_than_or_equal_to(:number, 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
if input <= value do
:ok
else
{:error, Zoi.Error.less_than_or_equal_to(:number, 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
if input > value do
:ok
else
{:error, Zoi.Error.greater_than(:number, 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
if input < value do
:ok
else
{:error, Zoi.Error.less_than(:number, 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: :number}
|> 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, value)
end
end