Current section
Files
Jump to
Current section
Files
lib/parser/local_ref.ex
defmodule Quenya.Parser.LocalRef do
@moduledoc """
Process local reference
"""
alias Quenya.Parser.Util
@doc """
Iterate the map and replace all $ref to the actual data
"""
@spec update(map()) :: {:ok, map()} | {:error, String.t()}
def update(data) do
with {:ok, comp} <- Map.fetch(data, "components"),
{:ok, comp1} <- do_extend_components(comp, "schemas"),
{:ok, comp2} <- do_extend_components(comp1, "parameters"),
{:ok, comp3} <- do_extend_components(comp2, "requestBodies"),
{:ok, comp4} <- do_extend_components(comp3, "responses"),
{:ok, paths} <- do_extend_paths(comp4, Map.get(data, "paths")) do
{:ok, %{data | "components" => comp4, "paths" => paths}}
else
e -> e
end
end
defp do_extend_components(data, type) do
recursive =
case type do
"schemas" -> true
_ -> false
end
updated =
Enum.reduce_while(data[type] || %{}, %{}, fn {k, v}, acc ->
result =
Util.update_map(
data,
v,
recursive,
fn context, path, recursive -> do_extend_ref(context, path, recursive) end
)
case result do
{:error, msg} -> {:halt, {:error, msg}}
_v -> {:cont, Map.put(acc, k, result)}
end
end)
case updated do
{:error, msg} -> {:error, msg}
_ -> {:ok, Map.put(data, type, updated)}
end
end
defp do_extend_paths(components, paths) do
updated =
Enum.reduce_while(paths, %{}, fn {k, v}, acc ->
result =
Util.update_map(
components,
v,
false,
fn context, path, recursive -> do_extend_ref(context, path, recursive) end
)
case result do
{:error, msg} -> {:halt, {:error, msg}}
_v -> {:cont, Map.put(acc, k, result)}
end
end)
case updated do
{:error, msg} -> {:error, msg}
_ -> {:ok, updated}
end
end
defp do_extend_ref(data, path, recursive) do
["#", _l1, l2, l3] = String.split(path, "/")
v = data[l2][l3]
case recursive do
true ->
Util.update_map(
data,
v,
recursive,
fn context, path, recursive -> do_extend_ref(context, path, recursive) end
)
_ ->
v
end
rescue
_ -> {:error, "failed to extend ref for #{path}"}
end
end