# `SnakeBridge.Generator.TypeMapper`
[🔗](https://github.com/nshkrdotcom/snakebridge/blob/v0.16.0/lib/snakebridge/generator/type_mapper.ex#L1)

Maps Python type annotations to Elixir typespec AST.

This module converts Python type dictionaries (as produced by the introspection
script) into Elixir typespec AST using `quote`. The AST can then be used to
generate `@spec` declarations in generated modules.

## Type Mappings

| Python Type | Elixir Type |
|------------|-------------|
| `int` | `integer()` |
| `float` | `float()` |
| `str` | `String.t()` |
| `bool` | `boolean()` |
| `bytes` | `binary()` |
| `None` | `nil` |
| `list[T]` | `list(T)` |
| `dict[K, V]` | `map(K, V)` |
| `tuple[T1, T2, ...]` | `{T1, T2, ...}` |
| `set[T]` | `MapSet.t(T)` |
| `Optional[T]` | `T \| nil` |
| `Union[T1, T2, ...]` | `T1 \| T2 \| ...` |
| `ClassName` | `ClassName.t()` |
| `Any` | `any()` |

## Examples

    iex> TypeMapper.to_spec(%{"type" => "int"})
    {:integer, [], []}

    iex> TypeMapper.to_spec(%{"type" => "list", "element_type" => %{"type" => "str"}})
    {{:., [], [{:__aliases__, [alias: false], [:String]}, :t]}, [], []}
    |> Macro.to_string()
    "list(String.t())"

# `context`

```elixir
@type context() :: %{
  class_map: %{required({String.t(), String.t()}) =&gt; String.t()},
  name_index: %{required(String.t()) =&gt; MapSet.t(String.t())}
}
```

# `build_context`

```elixir
@spec build_context([map()]) :: context()
```

# `to_spec`

```elixir
@spec to_spec(map() | nil) :: Macro.t()
```

Converts a Python type dictionary to an Elixir typespec AST.

## Parameters

  * `python_type` - A map representing a Python type annotation

## Returns

An AST node (quoted expression) representing the equivalent Elixir typespec.
Class types resolve to generated modules only when a context is provided
(via `to_spec/2` or `with_context/2`), otherwise they default to `term()`.

## Examples

    iex> python_type = %{"type" => "int"}
    iex> ast = SnakeBridge.Generator.TypeMapper.to_spec(python_type)
    iex> Macro.to_string(ast)
    "integer()"

    iex> python_type = %{"type" => "list", "element_type" => %{"type" => "int"}}
    iex> ast = SnakeBridge.Generator.TypeMapper.to_spec(python_type)
    iex> Macro.to_string(ast)
    "list(integer())"

# `to_spec`

```elixir
@spec to_spec(map() | nil, context()) :: Macro.t()
```

# `with_context`

```elixir
@spec with_context(context(), (-&gt; result)) :: result when result: var
```

---

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