ExParamsSchema.Definition.Field (ex_params_schema v0.1.1)

Copy Markdown View Source

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

normalized_array_type()

@type normalized_array_type() ::
  {kind :: :array, item_type :: normalized_type(),
   item_options :: ExParamsSchema.field_options()}

normalized_custom_type()

@type normalized_custom_type() ::
  {kind :: :custom, module :: module(), options :: keyword()}

normalized_enum_type()

@type normalized_enum_type() :: {kind :: :enum, allowed_values :: [atom()]}

normalized_object_type()

@type normalized_object_type() :: {kind :: :object, fields :: [t()]}

normalized_type()

t()

@type t() :: %ExParamsSchema.Definition.Field{
  name: atom(),
  options: ExParamsSchema.field_options(),
  type: normalized_type()
}

Functions

error_reason(field, inherited_reason \\ nil)

@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}

fetch_value(params, field)

@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

input_key(field)

@spec input_key(t()) :: String.t() | atom()

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"

missing_value(field)

@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

omit_from_validation?(field, arg2)

@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

optional?(field)

@spec optional?(t()) :: boolean()

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

optional_empty?(field, value)

@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

unknown_input_key(params, fields)

@spec unknown_input_key(map(), [t()]) :: term() | nil

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