View Source ExTerm.IOServer behaviour (ex_term v0.2.0)

behaviour template for implementing a server which responds to Robert Virding's IO Protocol:

https://www.erlang.org/doc/apps/stdlib/io_protocol.html

Warning

This module may be broken out into its own library in the future.

Link to this section Summary

Callbacks

responds to {:get_geometry, geometry} requests, where geometry may be either :rows or :columns

responds to :get_until, :get_chars, and :get_line requests in a single interface.

responds to :getopts requests.

responds to other messages.

responds to {:put_chars, encoding, characters} and {:put_chars, encoding, module, function, args} requests.

responds to other requests, these may not be defined at the time and may come in a future IO protocol spec.

responds to {:setopts, options} requests.

Link to this section Types

@type basic_reply() :: :ok | {:error, term()}
@type basic_response() ::
  {:ok, state()}
  | {:error, reason :: term(), state()}
  | reply(basic_reply())
  | noreply()
  | stop(basic_reply())
@type encoding() :: :latin | :unicode
@type from() :: GenServer.from()
@type geometry() :: :rows | :columns
@type get_condition() :: {:until, mfargs()} | {:chars, non_neg_integer()} | :line
@type get_reply() :: iodata() | :eof | {:error, term()}
@type mfargs() :: {module(), atom(), [term()]}
@type noreply() ::
  {:noreply, state()}
  | {:noreply, state(), timeout() | :hibernate | {:continue, term()}}
@type opt() ::
  :binary
  | :list
  | :unicode
  | :latin1
  | {:binary, boolean()}
  | {:echo, boolean()}
  | {:expand_fun, (... -> any())}
  | {:encoding, :unicode | :latin1}
  | {atom(), term()}
@type opts() :: [opt()]
@type reply(type) ::
  {:reply, type, state()}
  | {:reply, type, state(), timeout() | :hibernate | {:continue, term()}}
@type response(type) ::
  {:ok, type, state()}
  | {:error, reason :: term(), state()}
  | reply(type)
  | noreply()
  | stop(type)
@type state() :: term()
@type stop(type) :: {:stop, reason :: term(), type, state()}

Link to this section Callbacks

Link to this callback

handle_geometry(geometry, from, state)

View Source
@callback handle_geometry(geometry(), from(), state()) :: response(non_neg_integer())

responds to {:get_geometry, geometry} requests, where geometry may be either :rows or :columns

This request expects a reply of integer or {:error, error} in one of the following ways:

  • {:error, error, state} return value
  • {:reply, reply, state, ...} return value
  • {:noreply, state, ...} return followed by reply(from, reply) asynchronously.
Link to this callback

handle_get(encoding, prompt, get_condition, from, state)

View Source
@callback handle_get(encoding(), prompt :: iodata(), get_condition(), from(), state()) ::
  response(get_reply())

responds to :get_until, :get_chars, and :get_line requests in a single interface.

These requests constitute:

  • {:get_until, encoding, prompt, module, function, extraargs}
  • {:get_chars, encoding, prompt, count}
  • {:get_line, encoding, prompt}

The get_condition is packaged in the following ways:

  • for :get_until, it is passed as {:until, {module, function, args}}.
  • for :get_chars, it is passed as {:chars, count}
  • for :get_line, it is passed as :line

This request expects a reply of data :eof or {:error, error} in one of the following ways:

  • {:error, error, state} return value
  • {:reply, reply, state, ...} return value
  • {:noreply, state, ...} return followed by reply(from, reply) asynchronously.

Tip

Typically for this function, an asynchronous response is expected.

Link to this callback

handle_getopts(from, state)

View Source
@callback handle_getopts(from(), state()) :: response(keyword())

responds to :getopts requests.

This request expects a reply of keywordlist or {:error, error} in one of the following ways:

  • {:error, error, state} return value
  • {:reply, reply, state, ...} return value
  • {:noreply, state, ...} return followed by reply(from, reply) asynchronously.
Link to this callback

handle_message(term, state)

View Source (optional)
@callback handle_message(term(), state()) ::
  noreply() | {:stop, reason :: term(), state()}

responds to other messages.

Since IOServer takes over the GenServer.handle_info/2 callback, this callback can be used to listen to other messages.

Link to this callback

handle_put(encoding, arg2, from, state)

View Source
@callback handle_put(encoding(), iodata() | mfargs(), from(), state()) :: basic_response()

responds to {:put_chars, encoding, characters} and {:put_chars, encoding, module, function, args} requests.

In the case module, function and args are provided, these are merged into a single tuple and passed as the second parameter.

This request expects a reply of :ok or {:error, error} in one of the following ways:

  • {:ok, state} return value
  • {:error, error, state} return value
  • {:reply, reply, state, ...} return value
  • {:noreply, state, ...} return followed by reply(from, reply) asynchronously.
Link to this callback

handle_request(term, from, state)

View Source (optional)
@callback handle_request(term(), from(), state()) :: response(term())

responds to other requests, these may not be defined at the time and may come in a future IO protocol spec.

A default implementation is provided which emits an standard response for forwards compatibility.

Link to this callback

handle_setopts(opts, from, state)

View Source
@callback handle_setopts(opts(), from(), state()) :: basic_response()

responds to {:setopts, options} requests.

This request expects a reply of :ok or {:error, error} in one of the following ways:

  • {:ok, state} return value
  • {:error, error, state} return value
  • {:reply, reply, state, ...} return value
  • {:noreply, state, ...} return followed by reply(from, reply) asynchronously.

Link to this section Functions