lib/ex_zstd/cctx.ex

defmodule ExZstd.CCtx do
  @moduledoc """
  Compression context. To know more check out the `ExZstd` doc.
  """

  alias ExZstd.Cparam
  alias ExZstd.Nif

  defstruct []

  @opaque t() :: %__MODULE__{}

  @typep maybe(t, err) :: {:ok, t} | {:error, err}

  @type stream_end_directive() :: 0 | 1 | 2

  @spec stream_continue() :: 0
  def stream_continue, do: 0

  @spec stream_flush() :: 1
  def stream_flush, do: 1

  @spec stream_end() :: 2
  def stream_end, do: 2

  @doc """
  Creates a compression context.
  """
  @spec new() :: t()
  defdelegate new, to: Nif, as: :cctx_new

  @doc """
  Compresses a chunk of data.
  """
  @spec compress!(t(), binary()) :: binary()
  defdelegate compress!(cctx, data), to: Nif, as: :cctx_compress!

  @doc """
  Identical to `compress!`. Wraps the result in a maybe instead of raising.
  """
  @spec compress!(t(), binary()) :: maybe(binary(), ExZstd.error())
  def compress(cctx, data) do
    {:ok, compress!(cctx, data)}
  rescue
    error -> {:error, Exception.message(error)}
  end

  @doc """
  Gets the value of a parameter of a compression context (cparam).
  See `ExZstd.Cparam` for more information.
  """
  @spec get_cparam(t(), Cparam.t()) :: integer()
  defdelegate get_cparam(cctx, cparam), to: Nif, as: :cctx_get_cparam

  @doc """
  Sets a parameter of a compression context (cparam) to the given value.
  See `ExZstd.Cparam` for more information.
  """
  @spec set_cparam(t(), Cparam.t(), integer()) :: t()
  defdelegate set_cparam(cctx, cparam, value), to: Nif, as: :cctx_set_cparam

  @doc """
  Resets the compression context, interrupting any ongoing compression and resetting the parameters to their default values.
  """
  @spec reset(t(), ExZstd.reset_directive()) :: t()
  defdelegate reset(cctx, reset_directive), to: Nif, as: :cctx_reset

  @doc """
  Sets the size of the following frame, only effective with stream compression.
  """
  @spec set_pledged_src_size(t(), pos_integer()) :: t()
  defdelegate set_pledged_src_size(cctx, size), to: Nif, as: :cctx_set_pledged_src_size

  @doc """
  Loads a decompression dictionary inside the decompresson context.
  """
  @spec load_dictionary(t(), binary()) :: t()
  defdelegate load_dictionary(dctx, dictionary), to: Nif, as: :cctx_load_dictionary

  @doc """
  Writes a chunk of data into a compression stream.
  """
  @spec compress_stream!(t(), binary(), stream_end_directive()) :: binary()
  defdelegate compress_stream!(cctx, data, end_directive), to: Nif, as: :cctx_compress_stream!

  @doc """
  Identical to `compress_stream!`. Wraps the result in a maybe instead of raising.
  """
  @spec compress_stream(t(), binary(), stream_end_directive()) ::
          maybe(binary(), ExZstd.error())
  def compress_stream(cctx, data, end_directive) do
    {:ok, compress_stream!(cctx, data, end_directive)}
  rescue
    error -> {:error, Exception.message(error)}
  end
end