Estructura.WIA (estructura v1.15.0)

Copy Markdown View Source

Estructura.WIA (With Indifferent Access) provides a struct-like container that can be accessed by both atom and binary keys, replicating Ruby's Hash#with_indifferent_access pattern.

Internally, keys are always stored as atoms. Both atom and binary keys are accepted in Access operations and normalized to atoms transparently.

This module builds on top of Estructura, reusing its Access implementation, coercion, validation, and Enumerable protocol. It adds indifferent key normalization, and implements Inspect, Collectable, and optionally Jason.Encoder protocols to mimic map behaviour.

Usage

defmodule MyWIA do
  use Estructura.WIA,
    fields: [
      foo: [default: 42],
      bar: [default: ""],
      baz: [default: %{}]
    ]

  @impl MyWIA.Coercible
  def coerce_foo(value) when is_integer(value), do: {:ok, value}
  def coerce_foo(value) when is_binary(value) do
    case Integer.parse(value) do
      {int, ""} -> {:ok, int}
      _ -> {:error, "not a valid integer"}
    end
  end

  @impl MyWIA.Validatable
  def validate_foo(value) when value >= 0, do: {:ok, value}
  def validate_foo(_), do: {:error, ":foo must be non-negative"}
end

Then both atom and binary keys work interchangeably:

wia = %MyWIA{}
wia[:foo]        #=> 42
wia["foo"]       #=> 42
put_in(wia, ["foo"], 100)  #=> %MyWIA{foo: 100, ...}

Options

  • fields — a keyword list of {field_name, opts} where opts is a keyword list with:
    • :default — the default value for the field (default: nil)
    • :coerce — whether to generate a coercion callback for this field (default: false)
    • :validate — whether to generate a validation callback for this field (default: false)

Protocols

Inspect, Enumerable, and Collectable protocols are automatically implemented to mimic plain map behaviour. If Jason is compiled and available, Jason.Encoder is also derived.