isCanon static method
Reports whether keyExpr is a valid key expression in canon form.
Total: this never throws, on any input. It is the predicate to reach
for instead of constructing and catching — a bool answer costs no
allocation and no exception as control flow.
⚠️ false means "not a canon key expression" and nothing finer. It
covers both an invalid expression (a//b, a?b, the empty string)
and a merely non-canon one (a/**/**/c, which canonize rewrites
to a/**/c). Canon itself does not discriminate the two — it returns
the same code for both — so neither does this, rather than invent a
distinction the contract is not carrying. To tell them apart, ask
canonize: it succeeds on the second class and throws on the first.
isCanon(s) is true exactly when KeyExpr(s) constructs.
Validation only — nothing is constructed and nothing is sent — so
non-ASCII input is safe here, unlike a key expression handed to a
session operation (see the non-ASCII warning in this class's
documentation). keyExpr is judged as bytes, with the encode-boundary
caveat described there.
Implementation
static bool isCanon(String keyExpr) {
final encoded = utf8.encode(keyExpr);
// Never NULL, even for the empty string: canon builds a Rust slice from
// this pointer, slice::from_raw_parts(NULL, 0) is undefined behaviour,
// and this is the ONE entry in the canonization family canon does not
// NULL-guard itself. `_copyToNative` mallocs `len + 1`, so the pointer is
// valid at length 0 too.
final exprPtr = _copyToNative(encoded);
try {
return bindings.zd_keyexpr_is_canon(exprPtr.cast(), encoded.length) == 0;
} finally {
malloc.free(exprPtr);
}
}