Module cursor
Expand description
Opaque keyset-cursor encoding shared by generated list routes and
hand-written CursorPageInput/CursorPage<T> procedures
(docs/design/cursor-pagination.md).
A cursor is base64url(json({"o": <order>, "v": [<value>|null, ..]})):
the effective sort order it was minted for and the last row’s value
for each ordering column (primary-key tiebreaker last), each rendered
as the same wire string a ?field__gt= filter would carry. It is
not signed: the server never trusts it for anything a caller could
not already express as a filter — the decoded values re-enter the
normal typed filter path and are ANDed with the read policy.
Constants§
- MAX_
CURSOR_ LEN - Upper bound on an accepted cursor’s length in characters. Cursors are attacker-controlled input; this bounds decode work before any parsing.
Functions§
- cursor_
scalar - Render one ordering-column value as its cursor wire string through
serde (
DateTime→ RFC 3339,Uuid→ hyphenated, numbers → decimal).Nonefor SQLNULL. Arrays/objects are not orderable scalars. - decode_
cursor - Decode and validate a cursor against the order the request resolved
to. Every failure is a
CratestackError::BadRequest(RPCinvalid_argument): oversized, not base64url/JSON, minted for a different order, or carrying the wrong number of values. - encode_
cursor - Mint a cursor for
order(the canonical effective sort, e.g."-createdAt,id") from the last row’s per-column wire values;Noneis SQLNULL.