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

Metadata structure for computed fields in Exdantic schemas.

Computed fields are derived values that are calculated based on the validated
data after field and model validation. They extend the validated result with
additional computed information.

# `t`

```elixir
@type t() :: %Exdantic.ComputedFieldMeta{
  description: String.t() | nil,
  example: term() | nil,
  function_name: atom(),
  module: module(),
  name: atom(),
  readonly: boolean(),
  type: Exdantic.Types.type_definition()
}
```

# `function_reference`

```elixir
@spec function_reference(t()) :: String.t()
```

Returns a string representation of the computed field function reference.

## Parameters
  * `computed_field_meta` - The ComputedFieldMeta struct

## Returns
  * String in the format "Module.function/arity"

## Examples

    iex> meta = Exdantic.ComputedFieldMeta.new(:uppercased, {:type, :string, []}, :upcase, String)
    iex> Exdantic.ComputedFieldMeta.function_reference(meta)
    "String.upcase/1"

# `new`

```elixir
@spec new(atom(), Exdantic.Types.type_definition(), atom(), module()) :: t()
```

Creates a new ComputedFieldMeta struct.

## Parameters
  * `name` - The computed field name (atom)
  * `type` - The computed field type definition
  * `function_name` - The name of the function to call for computation
  * `module` - The module containing the computation function

## Examples

    iex> Exdantic.ComputedFieldMeta.new(:uppercased, {:type, :string, []}, :upcase, String)
    %Exdantic.ComputedFieldMeta{
      name: :uppercased,
      type: {:type, :string, []},
      function_name: :upcase,
      module: String,
      readonly: true
    }

# `set_readonly`

```elixir
@spec set_readonly(t(), boolean()) :: t()
```

Sets the readonly flag for a computed field metadata.

While computed fields are readonly by default, this function allows
explicit control over the readonly flag for special cases.

## Parameters
  * `computed_field_meta` - The ComputedFieldMeta struct
  * `readonly` - Whether the field should be marked as readonly

## Examples

    iex> meta = Exdantic.ComputedFieldMeta.new(:uppercased, {:type, :string, []}, :upcase, String)
    iex> updated = Exdantic.ComputedFieldMeta.set_readonly(meta, false)
    iex> updated.readonly
    false

# `to_map`

```elixir
@spec to_map(t()) :: %{
  name: atom(),
  type: Exdantic.Types.type_definition(),
  function_name: atom(),
  module: module(),
  description: String.t() | nil,
  example: term() | nil,
  readonly: boolean(),
  function_reference: String.t()
}
```

Converts computed field metadata to a map for debugging or serialization.

## Parameters
  * `computed_field_meta` - The ComputedFieldMeta struct

## Returns
  * Map representation of the computed field metadata

## Examples

    iex> meta = Exdantic.ComputedFieldMeta.new(:uppercased, {:type, :string, []}, :upcase, String)
    iex> |> Exdantic.ComputedFieldMeta.with_description("Uppercased version")
    iex> Exdantic.ComputedFieldMeta.to_map(meta)
    %{
      name: :uppercased,
      type: {:type, :string, []},
      function_name: :upcase,
      module: String,
      description: "Uppercased version",
      example: nil,
      readonly: true,
      function_reference: "String.upcase/1"
    }

# `validate_function`

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

Validates that the computation function exists in the specified module.

## Parameters
  * `computed_field_meta` - The ComputedFieldMeta struct

## Returns
  * `:ok` if the function exists and has the correct arity
  * `{:error, reason}` if the function is invalid

## Examples

    # For a module that exists with the function
    iex> meta = Exdantic.ComputedFieldMeta.new(:result, {:type, :string, []}, :upcase, String)
    iex> Exdantic.ComputedFieldMeta.validate_function(meta)
    :ok

    # For a module with a missing function
    iex> meta = Exdantic.ComputedFieldMeta.new(:bad_field, {:type, :string, []}, :missing_function, String)
    iex> Exdantic.ComputedFieldMeta.validate_function(meta)
    {:error, "Function String.missing_function/1 is not defined"}

# `with_description`

```elixir
@spec with_description(t(), String.t()) :: t()
```

Updates the description of a computed field metadata.

## Parameters
  * `computed_field_meta` - The ComputedFieldMeta struct
  * `description` - The description text

## Examples

    iex> meta = Exdantic.ComputedFieldMeta.new(:uppercased, {:type, :string, []}, :upcase, String)
    iex> updated = Exdantic.ComputedFieldMeta.with_description(meta, "Uppercased version")
    iex> updated.description
    "Uppercased version"

# `with_example`

```elixir
@spec with_example(t(), term()) :: t()
```

Adds an example value to a computed field metadata.

## Parameters
  * `computed_field_meta` - The ComputedFieldMeta struct
  * `example` - The example value

## Examples

    iex> meta = Exdantic.ComputedFieldMeta.new(:uppercased, {:type, :string, []}, :upcase, String)
    iex> updated = Exdantic.ComputedFieldMeta.with_example(meta, "HELLO")
    iex> updated.example
    "HELLO"

---

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