use alloc::borrow::Cow;
use alloc::string::String;
use core::fmt;
pub type Result<T> = core::result::Result<T, Error>;
#[non_exhaustive]
#[derive(Debug)]
pub enum Error {
Acquisition {
source: Cow<'static, str>,
reason: String,
},
KeyNotFound,
Fragment(String),
Defragment(String),
Decoy(String),
Codex(String),
LockedOut,
MemoryLock(String),
InvalidConfig(String),
Internal(&'static str),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Acquisition { source, reason } => {
write!(f, "key acquisition from {source} failed: {reason}")
}
Self::KeyNotFound => f.write_str("no key registered under the requested identifier"),
Self::Fragment(reason) => write!(f, "fragmentation failed: {reason}"),
Self::Defragment(reason) => write!(f, "defragmentation failed: {reason}"),
Self::Decoy(reason) => write!(f, "decoy generation failed: {reason}"),
Self::Codex(reason) => write!(f, "codex transformation failed: {reason}"),
Self::LockedOut => f.write_str("vault is locked out by security monitor threshold"),
Self::MemoryLock(reason) => write!(f, "memory lock operation failed: {reason}"),
Self::InvalidConfig(reason) => write!(f, "invalid vault configuration: {reason}"),
Self::Internal(reason) => write!(f, "internal vault invariant violated: {reason}"),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {}
#[cfg(test)]
mod tests {
use super::*;
use alloc::format;
use alloc::string::ToString;
#[test]
fn display_uses_sanitized_template() {
let e = Error::Acquisition {
source: Cow::Borrowed("keychain"),
reason: "user denied access".to_string(),
};
let rendered = format!("{e}");
assert!(rendered.contains("keychain"));
assert!(rendered.contains("user denied access"));
}
#[test]
fn key_not_found_has_stable_message() {
let rendered = format!("{}", Error::KeyNotFound);
assert!(rendered.contains("no key"));
}
#[test]
fn debug_does_not_panic_for_any_variant() {
for e in [
Error::KeyNotFound,
Error::Fragment("x".to_string()),
Error::Defragment("x".to_string()),
Error::Decoy("x".to_string()),
Error::Codex("x".to_string()),
Error::LockedOut,
Error::MemoryLock("x".to_string()),
Error::InvalidConfig("x".to_string()),
Error::Internal("x"),
] {
let _ = format!("{e:?}");
}
}
}