macro_rules! codes {
(
errors { $($(#[$error_doc:meta])* $error:ident = $error_code:literal;)* }
warnings { $($(#[$warning_doc:meta])* $warning:ident = $warning_code:literal;)* }
) => {
pub mod error {
$($(#[$error_doc])* pub const $error: &str = $error_code;)*
}
pub mod warning {
$($(#[$warning_doc])* pub const $warning: &str = $warning_code;)*
}
pub const ALL: &[&str] = &[$($error_code,)* $($warning_code,)*];
};
}
codes! {
errors {
IO = "E1000";
ELF = "E1001";
NOT_ELF = "E1002";
UNSUPPORTED_ARCHITECTURE = "E1003";
LIMIT_EXCEEDED = "E1005";
SOURCE_CHANGED = "E1006";
UNRESOLVED_LIBRARY = "E2001";
DISALLOWED_LIBRARY = "E2002";
INCOMPATIBLE_ARCHITECTURE = "E2003";
MISSING_RUNTIME_FILE = "E2004";
PATH_ESCAPE = "E3001";
MISSING_SOURCE_PATH = "E3002";
SYMLINK_LOOP = "E3003";
CONFIG = "E4001";
MANIFEST = "E4002";
VERIFY_FAILED = "E5001";
}
warnings {
DLOPEN = "E1004";
LIBRARY_UNREACHABLE = "E2005";
EXECUTABLE_RELOCATED = "E2006";
USER_WITHOUT_PASSWD_GROUP = "E4003";
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn no_two_diagnostics_share_a_code() {
let mut sorted = ALL.to_vec();
sorted.sort_unstable();
let mut unique = sorted.clone();
unique.dedup();
assert_eq!(sorted, unique, "a diagnostic code is used twice");
}
#[test]
fn codes_are_well_formed() {
for code in ALL {
let digits = code.strip_prefix('E').expect("codes start with `E`");
assert_eq!(digits.len(), 4, "{code}");
assert!(digits.bytes().all(|b| b.is_ascii_digit()), "{code}");
}
}
}