Packages
Terminal emulation and driver infrastructure for Raxol. ANSI parsing, screen buffers, command processing, cursor management, input handling, session management, and termbox2 NIF integration.
Current section
Files
Jump to
Current section
Files
lib/raxol/terminal/buffer/safe_manager.ex
defmodule Raxol.Terminal.Buffer.SafeManager do
@moduledoc """
Safe buffer manager that handles buffer operations with error recovery.
This module provides a safe interface to buffer operations, ensuring
that failures don't crash the system and providing fallback behavior.
"""
@doc """
Starts a safe manager process.
"""
@spec start_link() :: {:ok, pid()} | {:error, term()}
def start_link do
# For now, delegate to regular Manager
GenServer.start_link(Raxol.Terminal.ScreenBuffer.Manager, %{}, name: __MODULE__)
end
@doc """
Safely writes data to the buffer.
"""
@spec write(pid() | atom(), binary()) :: :ok | {:error, term()}
def write(manager, data) when is_binary(data) do
GenServer.call(manager, {:write, data})
rescue
error -> {:error, error}
catch
:exit, reason -> {:error, {:exit, reason}}
end
def write(_manager, _data), do: {:error, :invalid_data}
@doc """
Safely reads from the buffer.
"""
@spec read(pid() | atom(), non_neg_integer()) ::
{:ok, binary()} | {:error, term()}
def read(manager, count) when is_integer(count) and count > 0 do
GenServer.call(manager, {:read, count})
rescue
error -> {:error, error}
catch
:exit, reason -> {:error, {:exit, reason}}
end
def read(_manager, _count), do: {:error, :invalid_count}
@doc """
Safely resizes the buffer.
"""
@spec resize(pid() | atom(), non_neg_integer(), non_neg_integer()) ::
:ok | {:error, term()}
def resize(manager, width, height)
when is_integer(width) and width > 0 and
is_integer(height) and height > 0 do
GenServer.call(manager, {:resize, width, height})
rescue
error -> {:error, error}
catch
:exit, reason -> {:error, {:exit, reason}}
end
def resize(_manager, _width, _height), do: {:error, :invalid_dimensions}
@doc """
Safely clears the buffer.
"""
@spec clear(pid() | atom()) :: :ok | {:error, term()}
def clear(manager) do
GenServer.call(manager, :clear)
rescue
error -> {:error, error}
catch
:exit, reason -> {:error, {:exit, reason}}
end
@doc """
Gets buffer info safely.
"""
@spec info(pid() | atom()) :: {:ok, map()} | {:error, term()}
def info(manager) do
GenServer.call(manager, :info)
rescue
error -> {:error, error}
catch
:exit, reason -> {:error, {:exit, reason}}
end
@doc """
Safely gets a cell from the buffer.
"""
@spec get_cell(pid() | atom(), non_neg_integer(), non_neg_integer()) ::
{:ok, map()} | {:error, term()}
def get_cell(manager, x, y)
when is_integer(x) and x >= 0 and
is_integer(y) and y >= 0 do
GenServer.call(manager, {:get_cell, x, y})
rescue
error -> {:error, error}
catch
:exit, reason -> {:error, {:exit, reason}}
end
def get_cell(_manager, _x, _y), do: {:error, :invalid_coordinates}
@doc """
Safely sets a cell in the buffer.
"""
@spec set_cell(pid() | atom(), non_neg_integer(), non_neg_integer(), map()) ::
:ok | {:error, term()}
def set_cell(manager, x, y, cell)
when is_integer(x) and x >= 0 and
is_integer(y) and y >= 0 and
is_map(cell) do
GenServer.call(manager, {:set_cell, x, y, cell})
rescue
error -> {:error, error}
catch
:exit, reason -> {:error, {:exit, reason}}
end
def set_cell(_manager, _x, _y, _cell), do: {:error, :invalid_arguments}
@doc """
Safely scrolls the buffer.
"""
@spec scroll(pid() | atom(), integer()) :: :ok | {:error, term()}
def scroll(manager, lines) when is_integer(lines) do
GenServer.call(manager, {:scroll, lines})
rescue
error -> {:error, error}
catch
:exit, reason -> {:error, {:exit, reason}}
end
def scroll(_manager, _lines), do: {:error, :invalid_lines}
end