# `HexPort.Contract`
[🔗](https://github.com/mccraigmccraig/hex_port/blob/main/lib/hex_port/contract.ex#L1)

Macro for defining typed port contracts with `defport` declarations.

`use HexPort.Contract` imports the `defport` macro and registers a
`@before_compile` hook that generates:

  * `@callback` declarations on the contract module itself — the
    contract module *is* the behaviour
  * `__port_operations__/0` — introspection metadata

Contracts are purely static interface definitions. They do **not**
generate a dispatch facade (`.Port` module) — that is the concern of
`HexPort.Facade`, which the consuming application uses separately to
bind a contract to an OTP application's config.

## Usage

    defmodule MyApp.Todos do
      use HexPort.Contract

      defport get_todo(tenant_id :: String.t(), id :: String.t()) ::
        {:ok, Todo.t()} | {:error, term()}

      defport list_todos(tenant_id :: String.t()) :: [Todo.t()]
    end

This generates `@callback` declarations on `MyApp.Todos` and
`MyApp.Todos.__port_operations__/0`.

Implementations use `@behaviour MyApp.Todos` directly:

    defmodule MyApp.Todos.Ecto do
      @behaviour MyApp.Todos
      # ...
    end

Compatible with `Mox.defmock(Mock, for: MyApp.Todos)`.

To generate a dispatch facade, use `HexPort.Facade` in a separate module:

    defmodule MyApp.Todos do
      use HexPort.Facade, contract: MyApp.Todos.Contract, otp_app: :my_app
    end

See `HexPort.Facade` for dispatch configuration and `HexPort` for an overview.

# `defport`
*macro* 

Define a typed port operation.

## Syntax

    defport function_name(param :: type(), ...) :: return_type()
    defport function_name(param :: type(), ...) :: return_type(), bang: option

## Bang Options

  * **omitted** — auto-detect: generate bang only if return type contains `{:ok, T}`
  * **`true`** — force standard `{:ok, v}` / `{:error, r}` unwrapping
  * **`false`** — suppress bang generation
  * **`unwrap_fn`** — generate bang using custom unwrap function

## Pre-dispatch Transform

  * **`:pre_dispatch`** — a function `(args, facade_module) -> args` that
    transforms the argument list before dispatch. The function receives the
    args as a list and the facade module atom, and must return the
    (possibly modified) args list. This is useful for injecting
    facade-specific context into arguments at the dispatch boundary.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
