Packages

OCI/Docker image metadata validator and resolver for Elixir

Current section

Files

Jump to
regc lib regc oci client resolution.ex
Raw

lib/regc/oci/client/resolution.ex

defmodule Regc.Oci.Client.Resolution do
@moduledoc false
alias Regc.Oci.{Options, Platform}
alias Regc.Oci.Client.Resolution.{Budget, Path}
@enforce_keys [:opts, :platform, :path, :max_depth, :budget]
defstruct [:opts, :platform, :path, :max_depth, :budget]
@type t :: %__MODULE__{
opts: Options.t(),
platform: Platform.t() | nil,
path: Path.t(),
max_depth: non_neg_integer(),
budget: Budget.t()
}
@spec new(Options.t(), Platform.t() | nil, String.t()) :: t()
def new(%Options{} = opts, platform, root_digest) do
%__MODULE__{
opts: opts,
platform: platform,
path: Path.new(root_digest),
max_depth: opts.max_index_depth,
budget: Budget.new(opts.max_index_manifests)
}
end
@spec descend(t(), String.t(), Platform.t() | nil) :: t()
def descend(%__MODULE__{} = resolution, digest, selected_platform) do
%{resolution | path: Path.descend(resolution.path, digest, selected_platform)}
end
@spec consume_manifest(t()) :: {:ok, t()} | :exhausted
def consume_manifest(%__MODULE__{} = resolution) do
case Budget.consume(resolution.budget) do
{:ok, budget} -> {:ok, %{resolution | budget: budget}}
:exhausted -> :exhausted
end
end
@spec carry_budget(t(), t()) :: t()
def carry_budget(%__MODULE__{} = target, %__MODULE__{} = source) do
%{target | budget: source.budget}
end
@spec depth_limit_reached?(t()) :: boolean()
def depth_limit_reached?(%__MODULE__{} = resolution),
do: resolution.path.depth >= resolution.max_depth
@spec selected_platform(t()) :: Platform.t() | nil
def selected_platform(%__MODULE__{} = resolution),
do: resolution.path.selected_platform
@spec seen?(t(), String.t()) :: boolean()
def seen?(%__MODULE__{} = resolution, digest), do: Path.seen?(resolution.path, digest)
@spec manifest_limit(t()) :: non_neg_integer()
def manifest_limit(%__MODULE__{} = resolution), do: resolution.budget.limit
end