Concepts
Keys
DistkitRedisKey wraps and validates every key distkit writes to Redis.
Everything distkit stores in Redis is addressed by a DistkitRedisKey. It is a thin wrapper around a String that enforces a few rules up front, so an invalid key fails when you build it rather than deep inside a Lua script.
The rules
A key must be:
- non-empty,
- at most 255 bytes, and
- free of
:- the colon is reserved, because distkit uses it internally to namespace keys.
Constructing one
The fallible constructors return a Result (really a DistkitError::InvalidRedisKey on failure):
use distkit::DistkitRedisKey;
// TryFrom is the usual path.
let key = DistkitRedisKey::try_from("user_123".to_string())?;
// Equivalent explicit constructor.
let key = DistkitRedisKey::new("user_123".to_string())?;
If your input might contain colons, sanitize instead of failing:
// Strips colons, then validates the rest.
let key = DistkitRedisKey::try_sanitize("tenant:42".to_string())?; // -> "tenant42"
There are *_or_panic variants (new_or_panic, sanitize_or_panic) for cases where the key is a known-good constant and a bad value is genuinely a bug. Avoid them on anything derived from user input.
Prefixes vs keys
Counters take a prefix key (the namespace for that counter) and then individual item keys. Both are DistkitRedisKeys:
let prefix = DistkitRedisKey::try_from("my_app".to_string())?; // namespace
let key = DistkitRedisKey::try_from("page_views".to_string())?; // item within it
Practical advice
- Keep keys stable over their lifetime - a counter is only meaningful if the same subject maps to the same key.
- Keep them descriptive but bounded; you have 255 bytes, not a paragraph.

