pub fn hash_routing_key<'a>(
prefix: &str,
parts: impl Iterator<Item = &'a str>,
) -> StringExpand description
Hashes an ordered sequence of &str routing-hop parts into an opaque
"{prefix}:{digest:016x}" chain-identity key, using
std::collections::hash_map::DefaultHasher.
Extracted from three independently hand-rolled copies of this exact pattern
(deps_pypi::config::ResolvedChain::chain, deps_nuget::config::NuGetSourceChain::chain,
deps_go::config::GoProxyChain::keyed, #579) so “never hash a credential” is a property of
one function signature instead of a convention repeated in three doc comments.
Deliberately takes &str, not impl Hash: a caller with a typed credential wrapper (e.g.
NuGetAuth, which deliberately does not derive Hash — see its doc) must explicitly
convert it to a string before it can even be considered here, rather than being able to
.hash() the whole struct in place. Prefer a small, explicit, non-Debug as_key_str()-
style accessor on the hashed field’s own type over format!("{value:?}") at the call
site — chain identity would otherwise silently change if that type’s Debug output is
ever reworded (e.g. an enum variant rename), even though nothing routing-relevant changed.
Security invariant: parts must contain only routing-identity data (URLs, slot/hop
kind markers, boolean flags) — never credential material. Hashing a credential would
make the chain’s identity key change whenever that credential value rotates, defeating
rotation-stability guarantees callers rely on (e.g. NuGet issue #561’s FR-016). This
function has no way to enforce that; it is a caller obligation.
§Examples
use deps_core::hash_routing_key;
let key = hash_routing_key("pypi-chain", ["https://example.test/simple/", "true"].into_iter());
assert!(key.starts_with("pypi-chain:"));
assert_eq!(key.len(), "pypi-chain:".len() + 16);
// Same parts, same key — deterministic within a process.
let key2 = hash_routing_key("pypi-chain", ["https://example.test/simple/", "true"].into_iter());
assert_eq!(key, key2);
// Hop order is part of the identity.
let forward = hash_routing_key("go-proxy", ["a", "b"].into_iter());
let reversed = hash_routing_key("go-proxy", ["b", "a"].into_iter());
assert_ne!(forward, reversed);