pub const RESERVED: [&str; 7] = [
"error/invalid-args",
"error/unauthorized",
"error/not-found",
"error/unsupported",
"error/busy",
"error/gated",
"error/fanout-forbidden",
];
#[must_use]
pub fn is_reserved(name: &str) -> bool {
RESERVED.contains(&name)
}
#[must_use]
pub fn producer_error(producer: &str, name: &str) -> String {
format!("error/{producer}/{name}")
}
#[must_use]
pub fn is_valid_error_name(name: &str) -> bool {
!name.is_empty()
&& !name.starts_with('-')
&& !name.ends_with('-')
&& name
.bytes()
.all(|b| b.is_ascii_lowercase() || b.is_ascii_digit() || b == b'-')
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_reserved_list_is_the_rfcs() {
assert_eq!(RESERVED.len(), 7);
assert!(is_reserved("error/gated"));
assert!(is_reserved("error/fanout-forbidden"));
assert!(!is_reserved("error/modem/restart-required"));
}
#[test]
fn a_producer_error_is_namespaced_like_a_key() {
assert_eq!(
producer_error("modem", "restart-required"),
"error/modem/restart-required"
);
}
#[test]
fn error_names_are_plain_chunks() {
for ok in ["restart-required", "device-refused", "busy2"] {
assert!(is_valid_error_name(ok), "{ok}");
}
for bad in ["", "-x", "x-", "Restart", "a/b", "a b", "a_b"] {
assert!(!is_valid_error_name(bad), "{bad}");
}
}
}