pub fn funify_json(value: Value, f: &Funifier) -> ValueExpand description
Recursively walk a serde_json::Value and funify every value
whose containing key is NOT in Funifier::is_metric_passthrough.
Returns the funified value — input is consumed (cheaper than
cloning a deep tree).
Inverted polarity (metric allowlist): the default action is “funify it” — a value passes through unchanged ONLY when its containing key is a metric (count/rate/ratio/byte/duration/ structural enum). Any other field — pid, comm, cgroup_path, scheduler name, version string, novel identifier-shaped key the schema didn’t have last week — gets replaced.
Funification rules at the leaves:
- String under a non-metric key — replaced via
Funifier::petname_forusing the key name itself as the namespace. Two distinct keys with the same string value get different fun names; the same key + same value yields the same fun name everywhere in the dump (cross-reference preservation). - Integer (u64 or i64) under a non-metric key — replaced
via
Funifier::numeric_id/Funifier::numeric_id_i64with the key name as namespace. Sentinel zero andu64::MAXpass through unchanged (Funifier::is_sentinel_u64); the i64 path also preserves zero perFunifier::numeric_id_i64. - Float — always passes through. Floats are quasi- exclusively rates/ratios/durations in the dump schemas (cpu_time_fraction, wakeups_per_sec, …) and there is no sensible fun mapping for IEEE-754 values; making the rule uniform avoids hazarding the rate/ratio metrics that happen to live under non-metric-keyed parents (e.g. inside an anonymous-object array element).
- Bool / null — always pass through.
Recursive rules:
- Object — re-classify each key independently. Nested objects do NOT inherit metric state across the boundary.
- Array — children inherit the parent key’s
metric/non-metric verdict and (when non-metric) the parent
key’s namespace. So
"pids": [1, 2, 3]funifies each int under namespace “pids” and"counters": [...]passes every element through.