# `Estructura.Nested.Type.Struct`
[🔗](https://github.com/am-kantox/estructura/blob/v1.13.0/lib/estructura/nested/type/scaffold/struct.ex#L1)

`Estructura` type scaffold for creating validatable and coercible types for structs.

This module provides a way to create custom types for structs.

## Usage

There are two ways to use this type scaffold:

### 1. Using the module directly

    iex> require Estructura.Nested.Type.Struct
    ...> Estructura.Nested.Type.Struct.type_module_ast(Type.Money, [origin: Money]
    ...> apply(Type.Money, :validate, [Money.new!("100", :USD)])
    {:ok, :pending}
    iex> apply(Status, :validate, [:invalid])
    {:error, "Expected :invalid to be an instance of `Money` struct"}

### 2. Using the `use` macro

    iex> defmodule Price do
    ...>   use Estructura.Nested.Type.Struct, origin: Money
    ...> end
    ...> Role.validate(:admin)
    {:ok, :admin}

## Configuration Options

The scaffold accepts the following options:

- `:origin` - (required) The actual struct to be wrapped
- `:coercer` - (optional) Function to coerce input values
- `:encoder` - (optional) Function to encode values for JSON

### Example with Custom Coercion

    defmodule Price do
      use Estructura.Nested.Type.Struct,
        origin: Money,
        coercer: fn
          %Money{} = price -> {:ok, price}
          {amount, currency} -> with %Money{} = price <- Money.new(amount, currency), do: {:ok, price}
          other -> {:error, "Cannot coerce #{inspect(other)} to price"}
        end
    end

## Generated Functions

The scaffold implements the `Estructura.Nested.Type` behaviour and provides:

- `generate/1` - Generates random values from the enum for testing
- `coerce/1` - Attempts to convert input into a valid enum value
- `validate/1` - Ensures a value is part of the enum

### Generation Options

#### TBD

# `__using__`
*macro* 

Implements the struct type directly in the current module.

## Options

See the module documentation for available options.

## Examples

    defmodule Price do
      use Estructura.Nested.Type.Struct, origin: Money
    end

# `type_module_ast`

Creates a new struct type module with the given name and options.

## Options

See the module documentation for available options.

## Examples

```elixir
Estructura.Nested.Type.Struct.type_module_ast(__MODULE__, origin: Money)
```

---

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