# `WhatsApp.Deserializer`
[🔗](https://github.com/jeffhuen/whatsapp_sdk/blob/main/lib/whatsapp/deserializer.ex#L1)

Format-aware deserializer for WhatsApp API responses.

Converts JSON-decoded maps (with string keys) into typed Elixir structs.
Each service method knows its expected response type and passes it here for
structured deserialization.

## Features

- **String-key to atom-key mapping** -- maps `"field_name"` keys to struct
  atom fields automatically.
- **Format-aware casting** -- when the target module exposes a
  `__field_meta__/0` function, ISO 8601 date-time, date, and time strings
  are parsed into their respective Elixir structs (`DateTime`, `Date`,
  `Time`).
- **Nested resource deserialization** -- fields typed as `{:ref, Module}` or
  `{:array, {:ref, Module}}` are recursively deserialized.
- **Discriminator-based polymorphism** -- `deserialize_polymorphic/3`
  dispatches to the correct module based on a discriminator field value.

## Usage

    # Simple deserialization
    data = %{"id" => "123", "name" => "Test"}
    struct = WhatsApp.Deserializer.deserialize(data, MyApp.Resource)

    # List deserialization
    items = WhatsApp.Deserializer.deserialize_list(list_of_maps, MyApp.Resource)

    # Polymorphic dispatch
    mapping = %{"text" => TextMessage, "image" => ImageMessage}
    result = WhatsApp.Deserializer.deserialize_polymorphic(data, "type", mapping)

# `deserialize`

```elixir
@spec deserialize(map(), module()) :: struct()
```

Deserialize a string-keyed map into a struct of the given module.

Field values are cast according to the module's `__field_meta__/0` metadata
when available. Modules without `__field_meta__/0` get basic string-key to
atom-key mapping with no format casting.

Unknown keys in the data map are silently ignored. Missing keys default to
`nil` (or the struct's default value).

# `deserialize_list`

```elixir
@spec deserialize_list([map()], module()) :: [struct()]
```

Deserialize a list of string-keyed maps into a list of structs.

# `deserialize_polymorphic`

```elixir
@spec deserialize_polymorphic(map(), String.t(), %{required(String.t()) =&gt; module()}) ::
  struct() | {:error, :unknown_type}
```

Deserialize a map using discriminator-based polymorphism.

Looks up the value of `discriminator_field` in the data map and resolves it
against the provided `mapping` to determine which module to deserialize into.

Returns `{:error, :unknown_type}` if the discriminator value is not found in
the mapping or the discriminator field is missing from the data.

## Parameters

- `data` -- the string-keyed map to deserialize
- `discriminator_field` -- the string key used as the discriminator
  (e.g., `"type"`)
- `mapping` -- a map from discriminator values to module names
  (e.g., `%{"text" => TextMessage, "image" => ImageMessage}`)

---

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