Current section
Files
Jump to
Current section
Files
lib/oaskit/internal/spec_dumper.ex
defmodule Oaskit.Internal.SpecDumper do
alias JSV.Codec
@moduledoc false
# dumps a normal spec to json
def to_json(normal_spec, opts) do
normal_spec
|> validate(opts)
|> prune()
|> encode(opts)
end
defp validate(spec, opts) do
_ =
case Oaskit.Internal.SpecValidator.validate(spec) do
{:ok, _} -> :ok
{:error, verr} -> handle_error(verr, opts)
end
spec
end
defp handle_error(verr, opts) do
case opts[:validation_error_handler] do
f when is_function(f) -> f.(verr)
_ -> :ok
end
end
defp prune(spec) do
JSV.Helpers.Traverse.prewalk(spec, fn
{:val, map} when is_map(map) -> Map.delete(map, "jsv-cast")
other -> elem(other, 1)
end)
end
defp encode(spec, %{pretty: true}) do
cond do
typefix(Codec.supports_ordered_formatting?()) ->
Codec.format_ordered_to_iodata!(spec, &key_sorter/2)
typefix(Codec.supports_formatting?()) ->
Codec.format_to_iodata!(spec)
:other ->
raise ArgumentError, "Pretty printing is not supported by #{Codec.codec()}."
end
end
defp encode(spec, _) do
Codec.encode!(spec)
end
@key_order Map.new(
Enum.with_index([
"openapi",
"title",
"info",
"tags",
"servers",
"security",
"components",
"schemas",
"responses",
"paths"
])
)
defp key_order do
@key_order
end
defp key_sorter(a, b) do
Map.get(key_order(), a, a) <= Map.get(key_order(), b, b)
end
defp typefix(v) do
Process.get(make_ref(), v)
end
end