Current section

Files

Jump to
readmix lib readmix context.ex
Raw

lib/readmix/context.ex

defmodule Readmix.Context do
alias Readmix.Blocks.Generated
@moduledoc """
Helpers to access the context in generator actions.
"""
defstruct previous_content: [], readmix: nil, siblings: {[], []}, block: nil
@type t :: %__MODULE__{}
@doc """
Returns a function that reads the given var from the given context.
The returned function with throw `{:undef_var, key}` if the variable is not
defined.
"""
def getter(%__MODULE__{} = context, key) do
fn -> expect_variable(context.readmix.vars, key) end
end
@doc false
def expect_variable(map, key) do
case Map.fetch(map, key) do
{:ok, value} -> value
:error -> throw({:undef_var, key})
end
end
@doc """
Returns a section from the current rendering context at the same nesting
level.
This function can only retrieve sections that are defined above the calling
generated block. If multiple sections share the same name, it will return the
closest section, _.i.e_ the last one in file order.
"""
def lookup_rendered_section(%__MODULE__{} = context, section_name) do
{previous, _} = context.siblings
case Enum.find(previous, fn
%Generated{section_name: ^section_name} -> true
_ -> false
end) do
%Generated{rendered: {_, _, _}} = section -> {:ok, section}
nil -> {:error, {:section_not_found, section_name}}
end
end
@spec error!(t, term) :: no_return
def error!(context, reason) do
%{block: %Readmix.Blocks.Generated{spec: spec, mod: mod, action: action, params: params}} =
context
raise Readmix.Error.of({:user_error, {mod, action, params, reason}}, spec.file, spec.loc)
end
end