use thiserror::Error;
pub type JwtResult<T> = Result<T, JwtError>;
#[derive(Error, Debug)]
pub enum JwtError {
#[error("Invalid token format: {0}")]
InvalidToken(String),
#[error("Token has expired")]
TokenExpired,
#[error("Token is not yet valid")]
TokenNotYetValid,
#[error("Invalid token signature")]
InvalidSignature,
#[error("Invalid algorithm: {0}")]
InvalidAlgorithm(String),
#[error("Invalid key format: {0}")]
InvalidKey(String),
#[error("Missing required claim: {0}")]
MissingClaim(String),
#[error("Invalid claim value for '{0}': {1}")]
InvalidClaim(String, String),
#[error("JSON error: {0}")]
JsonError(#[from] serde_json::Error),
#[error("Base64 decode error: {0}")]
Base64Error(#[from] base64::DecodeError),
#[cfg(feature = "jsonwebtoken")]
#[error("JWT library error: {0}")]
JwtLibError(#[from] jsonwebtoken::errors::Error),
#[error("JWT error: {0}")]
Other(String),
}
impl JwtError {
pub fn invalid_token(msg: impl Into<String>) -> Self {
Self::InvalidToken(msg.into())
}
pub fn invalid_algorithm(alg: impl Into<String>) -> Self {
Self::InvalidAlgorithm(alg.into())
}
pub fn invalid_key(msg: impl Into<String>) -> Self {
Self::InvalidKey(msg.into())
}
pub fn missing_claim(claim: impl Into<String>) -> Self {
Self::MissingClaim(claim.into())
}
pub fn invalid_claim(claim: impl Into<String>, reason: impl Into<String>) -> Self {
Self::InvalidClaim(claim.into(), reason.into())
}
pub fn other(msg: impl Into<String>) -> Self {
Self::Other(msg.into())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_creation() {
let err = JwtError::invalid_token("malformed");
assert!(err.to_string().contains("malformed"));
let err = JwtError::missing_claim("sub");
assert!(err.to_string().contains("sub"));
let err = JwtError::invalid_claim("exp", "not a number");
assert!(err.to_string().contains("exp"));
assert!(err.to_string().contains("not a number"));
}
#[test]
fn test_error_display() {
assert_eq!(JwtError::TokenExpired.to_string(), "Token has expired");
assert_eq!(JwtError::TokenNotYetValid.to_string(), "Token is not yet valid");
assert_eq!(JwtError::InvalidSignature.to_string(), "Invalid token signature");
}
}