lib/membrane/component_path.ex

defmodule Membrane.ComponentPath do
  @moduledoc """
  Traces element's path inside a pipeline.
  Path is a list consisted of following pipeline/bin/element names down the assembled pipeline.
  Information is being stored in a process dictionary and can be set/appended to.
  """

  @type path_t :: list(String.t())

  @key :membrane_path

  @doc """
  Appends given name to the current path.

  If path has not been previously set then creates new one with given name.
  """
  @spec append(String.t()) :: :ok
  def append(name) do
    path = Process.get(@key, [])
    Process.put(@key, path ++ [name])
    :ok
  end

  @doc """
  Sets current path.

  If path had already existed then replaces it.
  """
  @spec set(path_t) :: :ok
  def set(path) do
    Process.put(@key, path)
    :ok
  end

  @doc """
  Convenient combination of `set/1` and `append/1`.
  """
  @spec set_and_append(path_t(), String.t()) :: :ok
  def set_and_append(path, name) do
    :ok = set(path)
    append(name)
  end

  @doc """
  Returns formatted string of given path's names joined with separator.
  """
  @spec format(path_t(), String.t()) :: String.t()
  def format(path, separator \\ "/") do
    path |> Enum.join(separator)
  end

  @doc """
  Works the same as `format/2` but uses currently stored path
  """
  @spec get_formatted(String.t()) :: String.t()
  def get_formatted(separator \\ "/") do
    Process.get(@key, []) |> format(separator)
  end

  @doc """
  Returns currently stored path.

  If path has not been set, empty list is returned.
  """
  @spec get() :: list(String.t())
  def get(), do: Process.get(@key, [])
end