An internal struct that represents a normalized field definition.
It provides field-level common rules such as input keys, optionality, and error reasons.
Summary
Functions
Returns the error reason, preferring field-specific, inherited, then default values.
Fetches a field value from an input map.
Returns the key used to fetch a value from an input map.
Returns how to handle a field that has no input value.
Returns whether a field value should be omitted from JSON Schema validation data.
Returns whether the field is optional.
Returns whether an input value should be treated as absent for an optional field.
Returns the first input key that is not included in the field definitions.
Types
@type normalized_array_type() :: {kind :: :array, item_type :: normalized_type(), item_options :: ExParamsSchema.field_options()}
@type normalized_enum_type() :: {kind :: :enum, allowed_values :: [atom()]}
@type normalized_object_type() :: {kind :: :object, fields :: [t()]}
@type normalized_type() :: ExParamsSchema.scalar_field_type() | normalized_enum_type() | normalized_custom_type() | normalized_array_type() | normalized_object_type()
@type t() :: %ExParamsSchema.Definition.Field{ name: atom(), options: ExParamsSchema.field_options(), type: normalized_type() }
Functions
@spec error_reason(t(), ExParamsSchema.error_reason() | nil) :: ExParamsSchema.error_reason()
Returns the error reason, preferring field-specific, inherited, then default values.
iex> field = %ExParamsSchema.Definition.Field{name: :count, type: :integer, options: [error: :invalid_count]}
iex> ExParamsSchema.Definition.Field.error_reason(field, :invalid_params)
:invalid_count
iex> field = %ExParamsSchema.Definition.Field{name: :count, type: :integer}
iex> ExParamsSchema.Definition.Field.error_reason(field, :invalid_params)
:invalid_params
iex> field = %ExParamsSchema.Definition.Field{name: :count, type: :integer}
iex> ExParamsSchema.Definition.Field.error_reason(field)
{:invalid_param, :count}
@spec fetch_value(map(), t()) :: {:ok, ExParamsSchema.value()} | :error
Fetches a field value from an input map.
Prefers the key configured with source: and falls back to the field name's atom key when absent.
iex> field = %ExParamsSchema.Definition.Field{name: :count, type: :integer, options: [source: "input-count"]}
iex> ExParamsSchema.Definition.Field.fetch_value(%{"input-count" => "1", count: "2"}, field)
{:ok, "1"}
iex> field = %ExParamsSchema.Definition.Field{name: :count, type: :integer}
iex> ExParamsSchema.Definition.Field.fetch_value(%{"count" => "2"}, field)
{:ok, "2"}
iex> field = %ExParamsSchema.Definition.Field{name: :count, type: :integer}
iex> ExParamsSchema.Definition.Field.fetch_value(%{"input-count" => "1"}, field)
:error
Returns the key used to fetch a value from an input map.
iex> ExParamsSchema.Definition.Field.input_key(%ExParamsSchema.Definition.Field{name: :display_name, type: :string})
"display_name"
iex> ExParamsSchema.Definition.Field.input_key(%ExParamsSchema.Definition.Field{name: :display_name, type: :string, options: [source: "displayName"]})
"displayName"
@spec missing_value(t()) :: {:default, ExParamsSchema.value()} | :optional | :required
Returns how to handle a field that has no input value.
Prefers default: when present; otherwise, follows the optional: setting.
iex> field = %ExParamsSchema.Definition.Field{name: :count, type: :integer, options: [default: 0]}
iex> ExParamsSchema.Definition.Field.missing_value(field)
{:default, 0}
iex> field = %ExParamsSchema.Definition.Field{name: :label, type: :string, options: [optional: true]}
iex> ExParamsSchema.Definition.Field.missing_value(field)
:optional
iex> field = %ExParamsSchema.Definition.Field{name: :count, type: :integer}
iex> ExParamsSchema.Definition.Field.missing_value(field)
:required
@spec omit_from_validation?(t(), ExParamsSchema.value()) :: boolean()
Returns whether a field value should be omitted from JSON Schema validation data.
Only omits nil for optional: true; keeps nil for nullable: true as validation input.
iex> optional = %ExParamsSchema.Definition.Field{name: :label, type: :string, options: [optional: true]}
iex> ExParamsSchema.Definition.Field.omit_from_validation?(optional, nil)
true
iex> nullable = %ExParamsSchema.Definition.Field{name: :label, type: :string, options: [nullable: true]}
iex> ExParamsSchema.Definition.Field.omit_from_validation?(nullable, nil)
false
Returns whether the field is optional.
iex> ExParamsSchema.Definition.Field.optional?(%ExParamsSchema.Definition.Field{name: :label, type: :string, options: [optional: true]})
true
iex> ExParamsSchema.Definition.Field.optional?(%ExParamsSchema.Definition.Field{name: :label, type: :string})
false
@spec optional_empty?(t(), ExParamsSchema.value()) :: boolean()
Returns whether an input value should be treated as absent for an optional field.
For strings, whitespace-only values are treated as absent in addition to empty strings.
iex> field = %ExParamsSchema.Definition.Field{name: :label, type: :string, options: [optional: true]}
iex> ExParamsSchema.Definition.Field.optional_empty?(field, " ")
true
iex> field = %ExParamsSchema.Definition.Field{name: :label, type: :string}
iex> ExParamsSchema.Definition.Field.optional_empty?(field, " ")
false
Returns the first input key that is not included in the field definitions.
Each field allows both its source: key and its field name's atom key.
iex> fields = [%ExParamsSchema.Definition.Field{name: :count, type: :integer}]
iex> ExParamsSchema.Definition.Field.unknown_input_key(%{"count" => "1"}, fields)
nil
iex> ExParamsSchema.Definition.Field.unknown_input_key(%{"count" => "1", "extra" => "value", "extra2" => "value"}, fields)
"extra"
iex> fields = [%ExParamsSchema.Definition.Field{name: :count, type: :integer, options: [source: "input-count"]}]
iex> ExParamsSchema.Definition.Field.unknown_input_key(%{"input-count" => "1"}, fields)
nil