Current section

Files

Jump to
minipeg lib minipeg cache.ex
Raw

lib/minipeg/cache.ex

defmodule Minipeg.Cache do
use Minipeg.Types
alias Minipeg.{Failure, Input, Success}
@moduledoc ~S"""
Wrapping a map
"""
defstruct cache: %{}
@type storage_t :: {:success, ast_t(), Input.t()} | {:failure, binary(), Input.t()}
@type entry_t :: %{binary => storage_t()}
@type t :: %__MODULE__{cache: %{Input.position_t() => entry_t()}}
@spec empty() :: t()
def empty do
%__MODULE__{}
end
@spec lookup(t(), Input.t(), binary()) :: maybe(result_t())
def lookup(%__MODULE__{cache: cache}=wrapper, input, name) do
cache
|> Map.get(Input.position(input), %{})
|> Map.get(name)
|> to_result(wrapper)
end
@spec new(Input.position_t(), binary(), result_t()) :: t
def new(position, name, result) do
update(%__MODULE__{}, position, name, result)
end
@spec update(t(), Input.position_t(), binary(), result_t()) :: t
def update(%__MODULE__{cache: cache}=wrapper, position, name, result) do
storage = to_storage(result)
pmap = cache |> Map.get(position, %{}) |> Map.put(name, storage)
%{wrapper | cache: Map.put(cache, position, pmap)}
end
@spec to_result(maybe(storage_t()), t()) :: maybe(result_t())
defp to_result(maybe_result, cache)
defp to_result(nil, _), do: nil
defp to_result({:failure, reason, input}, cache), do: Failure.fail(reason, input, cache)
defp to_result({:success, ast, rest}, cache), do: Success.succeed(ast, rest, cache)
@spec to_storage(result_t()) :: storage_t()
defp to_storage(result)
defp to_storage(%Failure{reason: reason, input: input}), do: {:failure, reason, input}
defp to_storage(%Success{ast: ast, rest: input}), do: {:success, ast, input}
end
# SPDX-License-Identifier: Apache-2.0