Skip to main content

validate_resolved_path

Function validate_resolved_path 

Source
pub fn validate_resolved_path(path: &str) -> Result<(), PlaceholderRefusal>
Available on crate feature schema-validation only.
Expand description

Validate the COMPOSED path after substitution and before dispatch.

§Why a per-value check is insufficient by construction

This is a proof, not a caution. Two values that each pass validate_path_placeholder independently can compose into a refused form across adjacent placeholders:

  • /search/{a}{b} with a at 180 code points and b at 200 yields a 380-code-point segment — over the cap, with neither part over it.
  • /x/{a}{b} with a = "." and b = "." yields the segment .. — traversal — from two values neither of which contains the sequence.

Adjacency is reachable rather than theoretical: on the Code Mode surface the substitution is genuinely per-{key}, and the composed result is then parsed as a URL, which is where a composed traversal becomes a different endpoint.

§Contract

The same decode-once normalization as the per-value floor runs over the WHOLE path; then the path is split on / and each segment is refused when it is longer than PLACEHOLDER_MAX_LENGTH code points, equal to the parent-directory sequence, equal to a single dot, or empty other than the leading segment a path starting with / produces. A residual { or } is refused — an unsubstituted placeholder reaching the wire is its own defect — and ?, #, a backslash and any control byte are refused anywhere.

§The three empty-segment cases, decided rather than derived

The segment split reports an empty slice in three different situations, and they get three different answers on purpose:

PathVerdictWhy
/ACCEPTEDthe absolute root has no segments; it is the shortest legal absolute path and the target of a GET / operation
/a//brefuseda doubled separator changes the endpoint shape
/a/b/refusedthis is what /search/{v} composes to when v is empty — the empty-placeholder-at-the-tail case

The first was a defect until Phase 128 CR-01: it fell out of the index arithmetic (only index 0 is exempt, and a bare / produces empty slices at indices 0 AND 1) rather than out of a decision, so validate_resolved_path("/") refused and every call to a root operation failed at runtime with the param-agnostic param 'path segment' must not be empty.

The refusal is param-agnostic: it carries the fixed position path segment rather than a caller-supplied name, because the composition belongs to no single parameter.

§Errors

Err(PlaceholderRefusal) describing the position and the expectation, never the path.