# `PB.Adapter`
[🔗](https://github.com/hansihe/pb_ex/blob/v0.2.0/pb/lib/pb/adapter.ex#L1)

Message-level app/proto conversion spec.

Adapters bridge PB's native message shape and a caller-chosen application term
such as a tagged tuple, struct, or scalar. Each adapter registers two
`{module, function}` MFAs:

  * `:to_proto` — converts an application value to a message field map.
  * `:from_proto` — converts a message field map back to the application
    value.

Callbacks must return `{:ok, value} | {:error, reason}`.

Adapter conversion is one message level only. PB owns recursion into child
messages, so child message values in both callback directions use the schema's
native representation. In particular, `:to_proto` must emit native child
values, not already-converted protobuf maps for those children.

    adapter =
      %PB.Adapter{
        to_proto: {MyApp.TimestampCodec, :to_proto},
        from_proto: {MyApp.TimestampCodec, :from_proto},
        type: quote(do: DateTime.t())
      }

    PB.compile(descriptor_set,
      projections: [{:"google.protobuf.Timestamp", adapter: adapter}]
    )

The optional `:type` field carries an Elixir typespec used for
`PB.Adapter`-aware docs; it is otherwise inert. The fully-qualified
message name an adapter targets is supplied by the surrounding
`:projections` entry, not by the adapter struct itself.

# `mfa_ref`

```elixir
@type mfa_ref() :: {module(), atom()}
```

# `t`

```elixir
@type t() :: %PB.Adapter{
  from_proto: mfa_ref(),
  to_proto: mfa_ref(),
  type: term() | nil
}
```

---

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