# `Exdantic.Type`
[🔗](https://github.com/nshkrdotcom/exdantic/blob/v0.1.0/lib/exdantic/type.ex#L1)

Behaviour and macros for defining custom types.

This module provides the behaviour and utility functions for creating
custom types in Exdantic schemas with validation and coercion capabilities.

# `coerce_function`

```elixir
@type coerce_function() :: (term() -&gt; {:ok, term()} | {:error, term()})
```

# `coerce_rule`

```elixir
@type coerce_rule() :: coerce_function() | {module(), atom()} | nil
```

# `coerce_rule`
*optional* 

```elixir
@callback coerce_rule() :: coerce_rule()
```

# `custom_rules`
*optional* 

```elixir
@callback custom_rules() :: [atom()]
```

# `json_schema`

```elixir
@callback json_schema() :: map()
```

# `type_definition`

```elixir
@callback type_definition() :: Exdantic.Types.type_definition()
```

# `validate`

```elixir
@callback validate(term()) :: {:ok, term()} | {:error, term()}
```

# `__using__`
*macro* 

```elixir
@spec __using__(keyword()) :: Macro.t()
```

Provides functionality for defining custom types in Exdantic schemas.

When you `use Exdantic.Type`, your module gets:
- The `Exdantic.Type` behaviour
- Import of `Exdantic.Types` functions
- Type aliases for coercion functions
- A default implementation of validation with coercion support

## Examples

    defmodule MyApp.Types.Email do
      use Exdantic.Type

      def type_definition do
        {:type, :string, [format: ~r/^[^@]+@[^@]+.[^@]+$/]}
      end

      def json_schema do
        %{"type" => "string", "format" => "email"}
      end

      def validate(value) do
        case type_definition() |> Exdantic.Validator.validate(value) do
          {:ok, validated} -> {:ok, validated}
          {:error, _} -> {:error, "invalid email format"}
        end
      end
    end

---

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