Expand description
Data-model binding: JSON Pointer resolution, scopes, and formatString.
A2UI keeps UI structure and application state apart. Components reference state through JSON Pointers, resolved against the surface’s data model at render time.
§Absolute and relative paths
A2UI deliberately extends RFC 6901 with relative paths to make template iteration expressible:
- A path starting with
/is absolute and always resolves from the root of the data model, wherever the component sits in the tree. - A path not starting with
/is relative and resolves inside the current collection scope. A container whosechildrenis a template over/employeesopens one scope per element, sonameinside the template resolves to/employees/0/name,/employees/1/name, and so on.
Scope models exactly this: Scope::root for the default scope and
Scope::item to descend into one element of a bound collection.
§Stringification
Whenever a non-string is interpolated into text, the conversion is fixed by
spec so every renderer agrees: numbers and booleans use their standard
representation, null and missing paths become "", and objects and arrays
are stringified as compact JSON.
use ag_ui_a2ui::binding::Scope;
use serde_json::json;
let data = json!({"company": "Acme", "employees": [{"name": "Alice"}, {"name": "Bob"}]});
let root = Scope::root(&data);
let item = root.item("/employees", 1);
// Relative inside the collection scope, absolute escapes back to the root.
assert_eq!(item.format_string("${name} @ ${/company} (#${@index(offset: 1)})").unwrap(),
"Bob @ Acme (#2)");§Depth
Resolution walks a serde_json::Value, and a walk over a tree is a stack
frame per level unless something stops it. Two things do. Anything arriving
over the wire has already passed through serde_json, which refuses to
parse deeper than 127 levels, so a Value from a model or a transport is
bounded before this module sees it. On top of that,
Scope::resolve_dynamic and collect_bindings carry their own cap
(MAX_VALUE_DEPTH) for values built in memory, which serde_json does not
check. The component graph — where depth is genuinely unbounded — is walked
iteratively in crate::validate instead.
Structs§
- Binding
- One data-model path reference found inside a component.
- Scope
- An evaluation scope: a data model plus the collection context bindings resolve against.
Constants§
- MAX_
VALUE_ DEPTH - Deepest nesting these walks will descend into a value.
Traits§
- Function
Resolver - Supplies renderer-side functions to
formatStringbeyond the built-ins.
Functions§
- collect_
bindings - Every data-model path referenced anywhere inside a JSON value.
- stringify
- Renders a value as a string using A2UI’s fixed conversion rules.