# `AshPhoenixGenApi.Codec`
[🔗](https://github.com/ohhi-vn/ash_phoenix_gen_api/blob/v1.0.3/lib/ash_phoenix_gen_api/codec.ex#L1)

Encodes Ash resource struct results based on `result_encoder` configuration.

The `result_encoder` determines how the result returned from an Ash action
call is encoded before being returned to the caller. This module provides
the encoding functions used by the auto-generated code interface functions.

The `result_encoder` determines how the result returned from an Ash action
call is encoded before being returned to the caller. This module provides
the encoding functions used by the auto-generated code interface functions.

## Encoder Modes

- `:struct` — Return the Ash resource struct as-is (default, no encoding)
- `:map` — Convert the Ash resource struct to a map containing only public fields
  (using `Ash.Resource.Info.public_fields/1` to filter; falls back to `Map.from_struct/1`
  for non-Ash-resource structs)
- `{Module, :function, args}` — Custom encoder MFA. The function receives
  the result as its first argument, followed by `args`, and must return
  the encoded result.

## Encoding Behavior

### `encode_result/2` (for ok/error tuples)

Handles `{:ok, result}` and `{:error, error}` tuples returned by Ash actions.
Only encodes the value on success; errors are passed through unchanged.

For `:map` encoding:
- Single Ash resource structs are converted to maps containing only public fields
  (using `Ash.Resource.Info.public_fields/1` to filter)
- Lists of structs are mapped with each struct filtered to public fields
- Non-Ash-resource structs fall back to `Map.from_struct/1`
- The atom `:ok` (from destroy actions) is returned as-is
- Non-struct values are returned as-is

### `encode_value/2` (for direct values)

Encodes a value directly, used by bang (!) functions that already raise
on error. The encoding behavior is the same as `encode_result/2` but
operates on the raw value instead of an ok/error tuple.

## Usage

This module is primarily used internally by the generated code interface
functions. You typically don't call it directly, but you can if needed:

    # Encode an ok/error tuple result
    result = Ash.create(changeset)
    AshPhoenixGenApi.Codec.encode_result(result, :map)
    #=> {:ok, %{id: "...", name: "..."}}  # only public fields

    # Encode a direct value (from bang functions)
    record = Ash.create!(changeset)
    AshPhoenixGenApi.Codec.encode_value(record, :map)
    #=> %{id: "...", name: "..."}  # only public fields

    # Custom encoder MFA
    AshPhoenixGenApi.Codec.encode_value(record, {MyEncoder, :to_json, []})
    #=> MyEncoder.to_json(record)

# `result_encoder`

```elixir
@type result_encoder() :: :struct | :map | {module(), atom(), [any()]}
```

# `encode_result`

```elixir
@spec encode_result({:ok, term()} | {:error, term()} | :ok, result_encoder()) ::
  {:ok, term()} | {:error, term()} | :ok
```

Encodes the result of an Ash action call that returns an ok/error tuple.

Only encodes the value on success; errors are passed through unchanged.

## Parameters

  - `result` — An `{:ok, value}` or `{:error, error}` tuple
  - `encoder` — The encoder mode (`:struct`, `:map`, or `{Module, :function, args}`)

## Returns

- `{:ok, encoded_value}` on success
- `{:error, error}` on failure (passed through unchanged)

## Examples

    iex> AshPhoenixGenApi.Codec.encode_result({:ok, %MyResource{id: "1"}}, :struct)
    {:ok, %MyResource{id: "1"}}

    iex> AshPhoenixGenApi.Codec.encode_result({:ok, %MyResource{id: "1"}}, :map)
    {:ok, %{id: "1"}}  # only public fields from the Ash resource

    iex> AshPhoenixGenApi.Codec.encode_result({:error, :some_error}, :map)
    {:error, :some_error}

    iex> AshPhoenixGenApi.Codec.encode_result({:ok, :ok}, :map)
    {:ok, :ok}

# `encode_value`

```elixir
@spec encode_value(term(), result_encoder()) :: term()
```

Encodes a direct value using the specified encoder.

Used by bang (!) functions that already raise on error, so the value
is always a successful result.

## Parameters

  - `value` — The value to encode
  - `encoder` — The encoder mode (`:struct`, `:map`, or `{Module, :function, args}`)

## Returns

The encoded value.

## Examples

    iex> AshPhoenixGenApi.Codec.encode_value(%MyResource{id: "1"}, :struct)
    %MyResource{id: "1"}

    iex> AshPhoenixGenApi.Codec.encode_value(%MyResource{id: "1"}, :map)
    %{id: "1"}  # only public fields from the Ash resource

    iex> AshPhoenixGenApi.Codec.encode_value([%MyResource{id: "1"}], :map)
    [%{id: "1"}]  # each struct filtered to public fields

    iex> AshPhoenixGenApi.Codec.encode_value(:ok, :map)
    :ok

---

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