pub fn scan_depth_complexity(
query: &str,
_depth_limit: usize,
cost_per_field: &HashMap<String, u64>,
complexity_coefficient: u64,
) -> (usize, u64)Expand description
Scan a GraphQL query string for depth and complexity. This is a bounded hand-rolled scanner – it does NOT fully parse GraphQL. It counts:
- Depth: the maximum brace-nesting level.
{and(increase depth;}and)decrease it. The top-level operation body is depth 1 (the first{). Strings and comments are skipped so braces inside string literals or descriptions do not affect the count. - Complexity: the sum of per-field costs. A “field” is an
identifier that appears in a selection position – heuristically,
an identifier followed by optional arguments
(...)and/or a sub-selection{...}. Each field’s cost iscost_per_field[name]if present, elsecomplexity_coefficient.
The scanner is bounded by PARSE_DEPTH_CAP: if the brace nesting
exceeds it, the scan aborts and returns a depth of
PARSE_DEPTH_CAP + 1 (which will exceed any reasonable
depth_limit, failing the check closed).
This is intentionally conservative: it may over-count fields in edge cases (e.g. fragments, directives, aliases) but never under-count depth. Over-counting complexity fails closed (a legitimate query slightly over the limit is denied, which the operator can fix by raising the limit); under-counting would fail open (an abusive query slips through), which is the worse failure mode for a security control.