docs/datamodel.md's standing commitment discharged: one function, with
defined rules, that normalizes a value into _event.data per spec
B.2.8.1. <param> and <content> (under <donedata>) call it here;
namelist, <send>, and <invoke> extend it rather than reinventing it
when they land.
B.2.8.1's own ladder, and which rungs this function implements:
If the value is not already in the indicated format, the Processor SHOULD convert it to the indicated format. ... If the data consists unambiguously of key/value pairs (e.g., the params of a <send> element, or the fields of an HTML form), the Processor MUST convert this data to a set of key/value pairs, ... If the Processor supports JSON [RFC4627], and the data is a well-formed JSON expression, the Processor MUST parse it into a data structure ... If the data is a well-formed external parsed entity, and the Processor supports XML, the Processor MUST parse it into a DOM document ... Otherwise, the Processor MUST treat the data as a space-normalized string.
| B.2.8.1 rung | Implemented here? |
|---|---|
| Indicated format (SHOULD) | No - no content-type channel exists yet. |
| Key-value pairs (MUST) | Yes - the {:params, pairs} arm. |
| JSON (MUST, if supported) | Substituted by a predicator literal-parse rung: this engine's value space is predicator's (ADR-0004), not ECMAScript's/JSON's, so the same ground (numbers, booleans, strings, lists, maps) is covered without a JSON dependency. |
| XML DOM (MUST, if interpretable as XML) | No - Statifier.Document.Content's moduledoc already rejects carrying a DOM subtree in a Document struct. |
| Space-normalized string literal (MUST) | Yes - the fallback. |
Duplicate <param> keys. B.2.8.1: "In the case of duplicate keys, the
behavior is platform-specific." This project's call: fold in document
order with Map.put semantics, so the last occurrence of a duplicate
name wins - the same resolution an ECMAScript object literal gives
duplicate properties, and what a left-to-right fold produces with no
extra machinery.
:undefined versus nil. An empty rung - no <content> text, no
<param> pairs - returns :undefined: "no data", per
docs/adr/0037-unbound-spelled-undefined-at-the-writer.md. A genuinely
null value (<content>null</content>, <param expr="null"/>) returns
nil, predicator's own null, unchanged. The two are now distinguishable
end to end, all the way through Evaluator.bind/3 and into _event.data.
Summary
Functions
Normalizes input into an _event.data value per B.2.8.1, as detailed
in the moduledoc above.
Types
The three shapes a caller hands to coerce/1: an already-evaluated
value (never re-interpreted as text), raw <content> text (parsed or
space-normalized), or a <param> name/value list (folded into a map).