Current section
Files
Jump to
Current section
Files
lib/open_api/spec/helper.ex
defmodule OpenAPI.Spec.Helper do
@moduledoc false
alias OpenAPI.State
@doc "Run the given `decoder` while managing the state's paths."
@spec with_path(State.t(), State.yaml(), State.path_segment(), State.decoder()) ::
{State.t(), term}
def with_path(state, yaml, path_segment, decoder) do
original_base_file_path = state.base_file_path
original_current_file_path = state.current_file_path
original_last_ref_path = state.last_ref_path
state =
Map.merge(state, %{
base_file_path: [path_segment | original_base_file_path],
current_file_path: [path_segment | original_current_file_path],
last_ref_path: [path_segment | original_last_ref_path]
})
{state, result} = decoder.(state, yaml)
state =
Map.merge(state, %{
base_file_path: original_base_file_path,
current_file_path: original_current_file_path,
last_ref_path: original_last_ref_path
})
{state, result}
end
@doc "Run the given `decoder` after resolving a ref, if present."
@spec with_ref(State.t(), State.yaml(), State.decoder()) :: {State.t(), term}
def with_ref(state, %{"$ref" => ref}, decoder) do
[new_file, new_ref_path] = String.split(ref, "#")
new_file = Path.join(state.current_file, new_file) |> Path.expand()
new_ref_path_segments = String.split(new_ref_path, "/", trim: true)
original_last_ref_file = state.last_ref_file
original_last_ref_path = state.last_ref_path
new_ref = "#{new_file}##{new_ref_path}"
state =
Map.merge(state, %{
last_ref_file: new_file,
last_ref_path: Enum.reverse(new_ref_path_segments)
})
stored_yaml = state.refs[new_ref]
{state, yaml} =
if stored_yaml do
{state, stored_yaml}
else
state = OpenAPI.Reader.ensure_file(state, new_file)
yaml = get_in(state.files[new_file], new_ref_path_segments)
state = %State{state | refs: Map.put(state.refs, new_ref, yaml)}
{state, yaml}
end
{state, result} = decoder.(state, yaml)
state =
Map.merge(state, %{
last_ref_file: original_last_ref_file,
last_ref_path: original_last_ref_path
})
{state, result}
end
def with_ref(state, yaml, decoder), do: decoder.(state, yaml)
end