# `Exdantic.TypeAdapter.Instance`
[🔗](https://github.com/nshkrdotcom/exdantic/blob/v0.1.0/lib/exdantic/type_adapter/instance.ex#L1)

A reusable TypeAdapter instance for efficient validation and serialization.

This module provides a struct that encapsulates a type specification and
configuration options, allowing for efficient reuse of the same type
validation and serialization logic.

# `t`

```elixir
@type t() :: %Exdantic.TypeAdapter.Instance{
  config: map(),
  json_schema: map() | nil,
  normalized_type: Exdantic.Types.type_definition(),
  type_spec: Exdantic.TypeAdapter.type_spec()
}
```

# `dump`

```elixir
@spec dump(t(), term(), keyword()) :: {:ok, term()} | {:error, String.t()}
```

Serializes a value using this TypeAdapter instance.

## Parameters
  * `instance` - The TypeAdapter instance
  * `value` - The value to serialize
  * `opts` - Additional serialization options

## Returns
  * `{:ok, serialized_value}` on success
  * `{:error, reason}` on serialization failure

## Examples

    iex> adapter = Exdantic.TypeAdapter.Instance.new({:map, {:string, :any}})
    iex> Exdantic.TypeAdapter.Instance.dump(adapter, %{name: "John"})
    {:ok, %{"name" => "John"}}

# `dump_many`

```elixir
@spec dump_many(t(), [term()], keyword()) ::
  {:ok, [term()]} | {:error, %{required(integer()) =&gt; String.t()}}
```

Serializes multiple values efficiently using the same TypeAdapter instance.

## Parameters
  * `instance` - The TypeAdapter instance
  * `values` - List of values to serialize
  * `opts` - Serialization options

## Returns
  * `{:ok, serialized_values}` if all values serialize successfully
  * `{:error, errors_by_index}` if any serialization fails

## Examples

    iex> adapter = Exdantic.TypeAdapter.Instance.new(:string)
    iex> Exdantic.TypeAdapter.Instance.dump_many(adapter, ["a", "b", "c"])
    {:ok, ["a", "b", "c"]}

# `info`

```elixir
@spec info(t()) :: map()
```

Returns information about the TypeAdapter instance.

## Parameters
  * `instance` - The TypeAdapter instance

## Returns
  * Map with instance information

## Examples

    iex> adapter = Exdantic.TypeAdapter.Instance.new({:array, :string})
    iex> Exdantic.TypeAdapter.Instance.info(adapter)
    %{
      type_spec: {:array, :string},
      normalized_type: {:array, {:type, :string, []}, []},
      config: %{coerce: false, strict: false},
      has_cached_schema: true
    }

# `json_schema`

```elixir
@spec json_schema(
  t(),
  keyword()
) :: map()
```

Gets the JSON schema for this TypeAdapter instance.

If the schema was cached during creation, returns the cached version.
Otherwise, generates it on demand.

## Parameters
  * `instance` - The TypeAdapter instance
  * `opts` - JSON schema generation options

## Returns
  * JSON Schema map

## Examples

    iex> adapter = Exdantic.TypeAdapter.Instance.new(:string)
    iex> Exdantic.TypeAdapter.Instance.json_schema(adapter)
    %{"type" => "string"}

# `new`

```elixir
@spec new(
  Exdantic.TypeAdapter.type_spec(),
  keyword()
) :: t()
```

Creates a new TypeAdapter instance.

## Parameters
  * `type_spec` - The type specification to create an adapter for
  * `opts` - Configuration options

## Options
  * `:coerce` - Enable type coercion by default (default: false)
  * `:strict` - Enable strict validation by default (default: false)
  * `:cache_json_schema` - Pre-generate and cache JSON schema (default: true)

## Returns
  * TypeAdapter.Instance struct

## Examples

    iex> adapter = Exdantic.TypeAdapter.Instance.new(:string)
    %Exdantic.TypeAdapter.Instance{...}

    iex> adapter = Exdantic.TypeAdapter.Instance.new({:array, :integer}, coerce: true)
    %Exdantic.TypeAdapter.Instance{...}

# `update_config`

```elixir
@spec update_config(t(), map()) :: t()
```

Updates the configuration of a TypeAdapter instance.

## Parameters
  * `instance` - The TypeAdapter instance
  * `new_config` - Configuration options to merge

## Returns
  * Updated TypeAdapter instance

## Examples

    iex> adapter = Exdantic.TypeAdapter.Instance.new(:string)
    iex> updated = Exdantic.TypeAdapter.Instance.update_config(adapter, %{coerce: true})
    %Exdantic.TypeAdapter.Instance{config: %{coerce: true, ...}}

# `validate`

```elixir
@spec validate(t(), term(), keyword()) ::
  {:ok, term()} | {:error, [Exdantic.Error.t()]}
```

Validates a value using this TypeAdapter instance.

## Parameters
  * `instance` - The TypeAdapter instance
  * `value` - The value to validate
  * `opts` - Additional validation options (override instance defaults)

## Returns
  * `{:ok, validated_value}` on success
  * `{:error, errors}` on validation failure

## Examples

    iex> adapter = Exdantic.TypeAdapter.Instance.new(:string)
    iex> Exdantic.TypeAdapter.Instance.validate(adapter, "hello")
    {:ok, "hello"}

    iex> adapter = Exdantic.TypeAdapter.Instance.new(:integer, coerce: true)
    iex> Exdantic.TypeAdapter.Instance.validate(adapter, "123")
    {:ok, 123}

# `validate_many`

```elixir
@spec validate_many(t(), [term()], keyword()) ::
  {:ok, [term()]} | {:error, %{required(integer()) =&gt; [Exdantic.Error.t()]}}
```

Validates multiple values efficiently using the same TypeAdapter instance.

## Parameters
  * `instance` - The TypeAdapter instance
  * `values` - List of values to validate
  * `opts` - Validation options

## Returns
  * `{:ok, validated_values}` if all values are valid
  * `{:error, errors_by_index}` if any validation fails

## Examples

    iex> adapter = Exdantic.TypeAdapter.Instance.new(:integer)
    iex> Exdantic.TypeAdapter.Instance.validate_many(adapter, [1, 2, 3])
    {:ok, [1, 2, 3]}

    iex> Exdantic.TypeAdapter.Instance.validate_many(adapter, [1, "bad", 3])
    {:error, %{1 => [%Exdantic.Error{...}]}}

---

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