Packages

A library for parsing, inspecting and manipulating JSON Schema documents.

Current section

Files

Jump to
json_schema lib type_path.ex
Raw

lib/type_path.ex

defmodule JsonSchema.TypePath do
  @moduledoc ~S"""
  Module for creating, manipulating, and printing type paths.
  """

  @type t :: [String.t()]

  @doc ~S"""
  Converts a json schema path like "#/definitions/foo" into its corresponding
  `JsonSchema.TypePath`.

  ## Examples

      iex> JsonSchema.TypePath.from_string("")
      []

      iex> JsonSchema.TypePath.from_string("#")
      ["#"]

      iex> JsonSchema.TypePath.from_string("#/definitions/foo")
      ["#", "definitions", "foo"]

  """
  @spec from_string(String.t()) :: t
  def from_string(string) do
    string
    |> String.split("/")
    |> Enum.filter(fn segment -> segment != "" end)
  end

  @doc ~S"""
  Converts a `JsonSchema.TypePath` back to its string representation.

  ## Examples

      iex> JsonSchema.TypePath.to_string([])
      ""

      iex> JsonSchema.TypePath.to_string(["#"])
      "#"

      iex> JsonSchema.TypePath.to_string(["#", "definitions", "foo"])
      "#/definitions/foo"

  """
  @spec to_string(t) :: String.t()
  def to_string(segments) do
    segments |> Enum.join("/")
  end

  @doc ~S"""
  Adds a child to an existing `JsonSchema.TypePath`.

  ## Examples

      iex> JsonSchema.TypePath.add_child(["#", "definitions", "foo"], "")
      ["#", "definitions", "foo"]

      iex> JsonSchema.TypePath.add_child(["#", "definitions"], "bar")
      ["#", "definitions", "bar"]

  """
  @spec add_child(t, String.t()) :: t
  def add_child(segments, segment) do
    if segment != "" do
      segments ++ [segment]
    else
      segments
    end
  end

  @doc ~S"""
  Returns true if the specified type can be treated as a `JsonSchema.TypePath`. Note
  that it also returns false if the specified type is a string representation of
  a `JsonSchema.TypePath`.

  ## Examples

      iex> JsonSchema.TypePath.type_path?("")
      false

      iex> JsonSchema.TypePath.type_path?("#/definitions/foo")
      false

      iex> JsonSchema.TypePath.type_path?([])
      false

      iex> JsonSchema.TypePath.type_path?(["bar"])
      false

      iex> JsonSchema.TypePath.type_path?(["#"])
      true

      iex> JsonSchema.TypePath.type_path?(["#", "foo"])
      true

  """
  @spec type_path?(any) :: boolean
  def type_path?(path) do
    is_list(path) && length(path) > 0 && Enum.fetch!(path, 0) == "#"
  end
end