DoubleDown.Double.CanonicalHandlerState (double_down v0.60.1)

Copy Markdown View Source

State for DoubleDown.Double.canonical_handler/5.

Stored inline in HandlerMeta.Stateful.state when Double installs its canonical stateful handler. Tracks queued expectations, per-operation stubs, per-operation fakes, and the fallback handler (function, stateful fake, or module) with its associated state.

Fields

  • contract — the contract module this state belongs to (never nil)
  • expects%{operation => [fun | :passthrough]} queued expectations

  • fakes%{operation => fun} per-operation stateful fake overrides
  • stubs%{operation => fun} per-operation stateless stub functions
  • rejectsMapSet of operation atoms that must not be called
  • fallback — the fallback handler, one of:
    • nil — no fallback configured
    • {:stateless, fun} — stateless 3-arity function fallback
    • {:stateful, fun} — 4/5-arity stateful fake function
    • {:module, module} — module implementing the contract behaviour
  • fallback_state — domain state for stateful fakes (only meaningful when fallback is {:stateful, _})

Summary

Functions

Add a single expect entry for an operation.

Add multiple expect entries for an operation (e.g. from times: n).

Mark an operation/arity as rejected (must not be called).

Create a new canonical handler state for the given contract.

Pop the next expect entry for an operation.

Set a per-operation fake.

Update the fallback_state (used during dispatch).

Set a per-operation stub.

Check if an operation/arity has been rejected.

Set a module fallback.

Set a stateful function fallback with initial state.

Set a stateless function fallback.

Check if a stateful fallback is configured.

Types

fallback()

@type fallback() ::
  nil
  | {:stateless, DoubleDown.Contract.Dispatch.Types.stateless_fun()}
  | {:stateful, DoubleDown.Contract.Dispatch.Types.stateful_fun()}
  | {:module, module()}

t()

@type t() :: %DoubleDown.Double.CanonicalHandlerState{
  contract: module(),
  expects: %{
    required(atom()) => [DoubleDown.Double.Types.expect_fun() | :passthrough]
  },
  fakes: %{required(atom()) => DoubleDown.Double.Types.fake_fun()},
  fallback: fallback(),
  fallback_state: term(),
  rejects: term(),
  stubs: %{required(atom()) => DoubleDown.Double.Types.stub_fun()}
}

Functions

add_expect(state, operation, entry)

@spec add_expect(t(), atom(), DoubleDown.Double.Types.expect_fun() | :passthrough) ::
  t()

Add a single expect entry for an operation.

add_expects(state, operation, entries)

@spec add_expects(t(), atom(), [DoubleDown.Double.Types.expect_fun() | :passthrough]) ::
  t()

Add multiple expect entries for an operation (e.g. from times: n).

add_reject(state, operation, arity)

@spec add_reject(t(), atom(), non_neg_integer()) :: t()

Mark an operation/arity as rejected (must not be called).

new(contract)

@spec new(module()) :: t()

Create a new canonical handler state for the given contract.

pop_expect(state, operation)

@spec pop_expect(t(), atom()) ::
  {:ok, DoubleDown.Double.Types.expect_fun() | :passthrough, t()} | :none

Pop the next expect entry for an operation.

put_fake(state, operation, fun)

@spec put_fake(t(), atom(), DoubleDown.Double.Types.fake_fun()) :: t()

Set a per-operation fake.

put_fallback_state(state, new_fallback_state)

@spec put_fallback_state(t(), term()) :: t()

Update the fallback_state (used during dispatch).

put_stub(state, operation, fun)

@spec put_stub(t(), atom(), DoubleDown.Double.Types.stub_fun()) :: t()

Set a per-operation stub.

rejected?(canonical_handler_state, operation, arity)

@spec rejected?(t(), atom(), non_neg_integer()) :: boolean()

Check if an operation/arity has been rejected.

set_module_fallback(state, module)

@spec set_module_fallback(t(), module()) :: t()

Set a module fallback.

set_stateful_fallback(state, fun, init_state)

@spec set_stateful_fallback(
  t(),
  DoubleDown.Contract.Dispatch.Types.stateful_fun(),
  term()
) :: t()

Set a stateful function fallback with initial state.

set_stateless_fallback(state, fun)

@spec set_stateless_fallback(t(), DoubleDown.Contract.Dispatch.Types.stateless_fun()) ::
  t()

Set a stateless function fallback.

stateful_fallback?(canonical_handler_state)

@spec stateful_fallback?(t()) :: boolean()

Check if a stateful fallback is configured.