frenzy/lib/frenzy/json_schema.ex

40 lines
1.0 KiB
Elixir

defmodule Frenzy.JSONSchema do
@enforce_keys [:value, :schema]
defstruct [:value, :schema]
@type t() :: %__MODULE__{
value: map(),
schema: schema()
}
@type schema() ::
:string
| :boolean
| :integer
| {:list, schema()}
| %{required(String.t()) => schema()}
@spec coerce(schema :: schema(), value :: map() | list() | String.t()) :: map()
def coerce(:string, value) when is_binary(value), do: value
def coerce(:boolean, "true"), do: true
def coerce(:boolean, _), do: false
def coerce(:integer, value) when is_binary(value) do
{res, _} = Integer.parse(value)
res
end
def coerce({:list, list_type}, list_value) when is_list(list_value) do
Enum.map(list_value, &coerce(list_type, &1))
end
def coerce(schema, map_value) when is_map(schema) and is_map(map_value) do
Enum.reduce(schema, %{}, fn {key, value_schema}, acc ->
value = Map.fetch!(map_value, key)
Map.put(acc, key, coerce(value_schema, value))
end)
end
end