# `Statifier.Send.Target`
[🔗](https://github.com/riddler/statifier-ex/blob/v2.0.0/lib/statifier/send/target.ex#L1)

Spec 6.2.2's `target` attribute and C.1's special-target vocabulary,
parsed into a route, plus the supported-`type` predicate 6.2.5 asks for.
One pure module, no process, no effect calls - `Mix.Statifier.AdrGuard`
has nothing to say about it and no exemption is needed. It has two
consumers: the core's `<send>` node, which rejects a `{:invalid, _}`
target or an unsupported `type` under ADR-0047, and
`Statifier.Session.Effects`, which applies the same classification at
`Statifier.Session.interpret/2`'s boundary (ADR-0029).

Resolving a route into an actual delivery (or `error.communication`) is
`Statifier.Session`'s job, not this module's: this module only says *what
kind* of destination a target string names, never whether that
destination currently exists.

# `route`

```elixir
@type route() ::
  :self
  | :internal
  | {:session, String.t()}
  | :parent
  | {:invoke, String.t()}
  | {:invalid, String.t()}
```

What a `<send target>` names, before any session-runtime resolution:

- `:self` - no `target` at all; the sending session's own external queue.
- `:internal` - `#_internal`/`_internal` (C.1/6.2.2 disagree on the
  spelling; both are accepted, decision 6).
- `{:session, session_id}` - `#_scxml_<sessionid>`.
- `:parent` - `#_parent`.
- `{:invoke, invokeid}` - `#_<invokeid>`, any other `#_`-prefixed target.
  Reserved here; no bead resolves it yet (see the plan's "What We're NOT
  Doing" and "Follow-up work").
- `{:invalid, target}` - 6.2.4's "not supported or invalid" -
  `error.execution`, never delivered and never scheduled.

# `parse`

```elixir
@spec parse(target :: String.t() | nil) :: route()
```

Parses a `<send target>` string (or `nil`, meaning the attribute was
absent) into a `route()`. Never fails: every input string that names no
recognized special target becomes `{:invalid, target}` rather than
raising, so a planner can turn it into 6.2.4's `error.execution` with no
`case` fallback of its own to write.

# `scxml_invoke_type`

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

6.4.2's URI for `<invoke type>`, mandated verbatim: "Platforms MUST
support `http://www.w3.org/TR/scxml/` as a value for the 'type'
attribute." This is a **different string** from `supported_type?/1`'s
`SystemVariables.scxml_event_processor/0` URI
(`http://www.w3.org/TR/scxml/#SCXMLEventProcessor`): 6.4.2 names the bare
namespace URI for invoke's `type`, 6.2.5 names the processor URI with its
`#SCXMLEventProcessor` fragment for send's. Conflating the two would fail
the corpus in both directions - an `<invoke type="http://www.w3.org/TR/scxml/">`
rejected as unsupported, or a `<send type="http://www.w3.org/TR/scxml/">`
wrongly accepted.

# `supported_invoke_type?`

```elixir
@spec supported_invoke_type?(type :: String.t() | nil) :: boolean()
```

Whether `<invoke type>` names an SCXML-typed service (6.4.2).

`"scxml"` is licensed by 6.4.2 itself - "Processors MAY define short form
notations as an authoring convenience (e.g., "scxml" as equivalent to
`http://www.w3.org/TR/scxml/`)" - not borrowed from `<send>`'s own short
form.

`nil` (the attribute omitted) is accepted as SCXML-typed, but that is this
platform's choice rather than a spec default: 6.4.1's attribute table
gives `<invoke type>` a Default Value of "none", where 6.2.5 mandates one
for `<send>` ("If neither the 'type' nor the 'typeexpr' is defined, the
SCXML Processor MUST assume the default value of
`http://www.w3.org/TR/scxml/#SCXMLEventProcessor`"). Starting a child
session is the only invocation this engine implements, so an untyped
`<invoke>` has nothing else it could have meant.

Anything else - including `supported_type?/1`'s own processor URI - is
unsupported: this engine implements only SCXML-typed invocations (see the
plan's "What We're NOT Doing" on BasicHTTP and non-SCXML invoke types).

This predicate lives here, alongside `<send>`'s own, because it shares
6.4.2/6.2.5's short-form reasoning with its `<send>` sibling - not because
`<invoke>` is a send.

# `supported_type?`

```elixir
@spec supported_type?(type :: String.t() | nil) :: boolean()
```

Whether this Event I/O Processor supports `type` (6.2.5). `nil` (the
attribute omitted) defaults to the SCXML Event I/O Processor, which is
always supported. `"scxml"` is 6.2.5's explicitly-permitted short form
("Processors MAY define short form notations") - a MAY this codebase
chose to honor, not a MUST - and the processor's own type URI
(`SystemVariables.scxml_event_processor/0`) is the long form. Anything
else is unsupported: this engine implements only the SCXML Event I/O
Processor (see the plan's "What We're NOT Doing" on BasicHTTP).

---

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