use std::io;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Error, Debug)]
pub enum Error {
#[error("Storage error: {0}")]
Storage(String),
#[error("Configuration error: {0}")]
Config(String),
#[error("UHID error: {0}")]
Uhid(String),
#[error("Credential management error: {0}")]
CredentialManagement(String),
#[error("User verification failed: {0}")]
UserVerificationFailed(String),
#[error("Operation cancelled by user")]
Cancelled,
#[error("IO error: {0}")]
Io(#[from] io::Error),
#[error("Serialization error: {0}")]
Serialization(String),
#[error("Invalid data: {0}")]
InvalidData(String),
#[error("{0}")]
Other(String),
}
impl Error {
pub fn format_cli(&self) -> String {
match self {
Error::Storage(msg) => format!("Storage error: {}", msg),
Error::Config(msg) => format!("Configuration error: {}", msg),
Error::Uhid(msg) => format!("UHID error: {}", msg),
Error::CredentialManagement(msg) => format!("Credential management error: {}", msg),
Error::UserVerificationFailed(msg) => format!("User verification failed: {}", msg),
Error::Cancelled => "Operation cancelled by user".to_string(),
Error::Io(err) => format!("IO error: {}", err),
Error::Serialization(msg) => format!("Serialization error: {}", msg),
Error::InvalidData(msg) => format!("Invalid data: {}", msg),
Error::Other(msg) => msg.clone(),
}
}
}
impl From<soft_fido2::Error> for Error {
fn from(err: soft_fido2::Error) -> Self {
Error::CredentialManagement(format!("{:?}", err))
}
}
impl From<Error> for soft_fido2::Error {
fn from(err: Error) -> Self {
match err {
Error::Storage(ref msg) if msg.contains("not found") => soft_fido2::Error::DoesNotExist,
Error::Storage(ref msg) if msg.contains("No more credentials") => {
soft_fido2::Error::DoesNotExist
}
_ => soft_fido2::Error::Other,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_soft_fido2_error_conversion() {
let err: Error = soft_fido2::Error::DoesNotExist.into();
assert!(matches!(err, Error::CredentialManagement(_)));
let err: soft_fido2::Error = Error::Storage("not found".to_string()).into();
assert!(matches!(err, soft_fido2::Error::DoesNotExist));
}
}