use std::fmt;
pub type NythosResult<T> = Result<T, AuthError>;
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AuthError {
UserNotFound,
InvalidCredentials,
AccountLocked,
SessionRevoked,
SessionExpired,
TenantNotFound,
PermissionDenied,
ValidationError(String),
Internal(String),
}
impl fmt::Display for AuthError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AuthError::UserNotFound => f.write_str("user not found"),
AuthError::InvalidCredentials => f.write_str("invalid credentials"),
AuthError::AccountLocked => f.write_str("account locked"),
AuthError::SessionRevoked => f.write_str("session revoked"),
AuthError::SessionExpired => f.write_str("session expired"),
AuthError::TenantNotFound => f.write_str("tenant not found"),
AuthError::PermissionDenied => f.write_str("permission denied"),
AuthError::ValidationError(msg) => write!(f, "validation error: {}", msg),
AuthError::Internal(msg) => write!(f, "internal error: {}", msg),
}
}
}
impl std::error::Error for AuthError {}
#[cfg(test)]
mod tests {
use super::{AuthError, NythosResult};
#[test]
fn string_payload_variants_preserve_messages() {
let validation_error = AuthError::ValidationError("invalid email".to_owned());
let internal_error = AuthError::Internal("signer unavailable".to_owned());
assert_eq!(
validation_error.to_string(),
"validation error: invalid email"
);
assert_eq!(
internal_error.to_string(),
"internal error: signer unavailable"
);
}
#[test]
fn unit_variants_match_as_expected() {
let err = AuthError::InvalidCredentials;
assert!(matches!(err, AuthError::InvalidCredentials));
assert_ne!(err, AuthError::UserNotFound);
}
#[test]
fn display_messages_are_transport_agnostic() {
assert_eq!(AuthError::UserNotFound.to_string(), "user not found");
assert_eq!(
AuthError::ValidationError("bad input".to_owned()).to_string(),
"validation error: bad input"
);
assert_eq!(
AuthError::Internal("store failed".to_owned()).to_string(),
"internal error: store failed"
);
}
#[test]
fn nythos_result_alias_uses_auth_error() {
fn fails() -> NythosResult<()> {
Err(AuthError::SessionExpired)
}
let result = fails();
assert!(matches!(result, Err(AuthError::SessionExpired)));
}
}