Canonical address for an event in the Mob view tree.
An address identifies where a widget lives (screen and component_path)
and what fired (widget, id, instance). It also carries render_id
so handlers can detect events from prior render generations.
See guides/event_model.md for the full event model.
Example
%Mob.Event.Address{
screen: MyApp.CheckoutScreen,
component_path: [:checkout_form],
widget: :button,
id: :submit,
instance: nil,
render_id: 42
}
Summary
Types
Anything pattern-matchable that survives serialisation. Atoms are best for compile-time-known IDs; binaries for data-derived ones (DB IDs, UUIDs); integers/tuples for indices and compound keys.
Functions
True if addr.render_id matches current_render_id.
Build an address. screen, widget, and id are required. The rest take
reasonable defaults.
True if the address points to the same logical widget as other. Ignores
render_id — useful for "is this another tap on the same button?" checks.
Format an address as a short, human-readable string for logs.
Validate that id is one of the supported types. Returns :ok or
{:error, reason}.
Bump the render id on an address (e.g. when re-registering a widget after a render). Returns a new address; original is unchanged.
Types
Anything pattern-matchable that survives serialisation. Atoms are best for compile-time-known IDs; binaries for data-derived ones (DB IDs, UUIDs); integers/tuples for indices and compound keys.
Floats, maps, and lists are technically allowed but discouraged: floats have fuzzy equality, maps and lists are heavy to hash on every event.
Pids, refs, and funs are explicitly forbidden — they don't survive serialisation and can't be the basis of a stable address across re-renders.
Functions
@spec current?(t(), pos_integer()) :: boolean()
True if addr.render_id matches current_render_id.
Use to detect stale events arriving after a re-render.
Build an address. screen, widget, and id are required. The rest take
reasonable defaults.
iex> Mob.Event.Address.new(screen: MyScreen, widget: :button, id: :save)
%Mob.Event.Address{screen: MyScreen, widget: :button, id: :save, component_path: [], instance: nil, render_id: 1}
iex> Mob.Event.Address.new(screen: MyScreen, widget: :list, id: :contacts, instance: 47, render_id: 12)
%Mob.Event.Address{screen: MyScreen, widget: :list, id: :contacts, instance: 47, component_path: [], render_id: 12}
True if the address points to the same logical widget as other. Ignores
render_id — useful for "is this another tap on the same button?" checks.
Format an address as a short, human-readable string for logs.
iex> Mob.Event.Address.to_string(%Mob.Event.Address{screen: MyScreen, widget: :button, id: :save})
"MyScreen→button#save"
iex> Mob.Event.Address.to_string(%Mob.Event.Address{screen: MyScreen, component_path: [:form], widget: :text_field, id: :email})
"MyScreen/form→text_field#email"
iex> Mob.Event.Address.to_string(%Mob.Event.Address{screen: MyScreen, widget: :list, id: :contacts, instance: 47})
"MyScreen→list#contacts[47]"
Validate that id is one of the supported types. Returns :ok or
{:error, reason}.
Used by Mob.Renderer and Mob.Event to fail fast when an obviously-bad
ID is passed (e.g. a pid, a function, or an undefined value).
iex> Mob.Event.Address.validate_id(:save)
:ok
iex> Mob.Event.Address.validate_id("contact:42")
:ok
iex> Mob.Event.Address.validate_id(42)
:ok
iex> Mob.Event.Address.validate_id(self())
{:error, :pid_not_allowed}
iex> Mob.Event.Address.validate_id(nil)
{:error, :nil_not_allowed}
@spec with_render_id(t(), pos_integer()) :: t()
Bump the render id on an address (e.g. when re-registering a widget after a render). Returns a new address; original is unchanged.