use thiserror::Error;
#[derive(Error, Debug)]
pub enum WalletError {
#[error("Database not found: {0}")]
DatabaseNotFound(String),
#[error("Invalid password")]
InvalidPassword,
#[error("Wallet is locked")]
Locked,
#[error("Encryption error: {0}")]
EncryptionError(String),
#[error("Decryption error: {0}")]
DecryptionError(String),
#[error("Database error: {0}")]
DatabaseError(String),
#[error("Backup error: {0}")]
BackupError(String),
#[error("Item not found: {0}")]
ItemNotFound(String),
#[error("Field not found: {0}")]
FieldNotFound(String),
#[error("Label not found: {0}")]
LabelNotFound(String),
#[error("Invalid database version: {0}")]
InvalidVersion(String),
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("Invalid operation: {0}")]
InvalidOperation(String),
#[error("Localization error: {0}")]
LocalizationError(String),
#[error("Export error: {0}")]
ExportError(String),
}
impl From<rusqlite::Error> for WalletError {
fn from(err: rusqlite::Error) -> Self {
WalletError::DatabaseError(err.to_string())
}
}
impl From<zip::result::ZipError> for WalletError {
fn from(err: zip::result::ZipError) -> Self {
WalletError::BackupError(err.to_string())
}
}
pub type Result<T> = std::result::Result<T, WalletError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let err = WalletError::DatabaseNotFound("/path/to/db".to_string());
assert!(err.to_string().contains("/path/to/db"));
let err = WalletError::InvalidPassword;
assert_eq!(err.to_string(), "Invalid password");
let err = WalletError::Locked;
assert_eq!(err.to_string(), "Wallet is locked");
let err = WalletError::EncryptionError("test error".to_string());
assert!(err.to_string().contains("test error"));
let err = WalletError::ItemNotFound("item123".to_string());
assert!(err.to_string().contains("item123"));
let err = WalletError::InvalidVersion("999".to_string());
assert!(err.to_string().contains("999"));
}
#[test]
fn test_error_from_rusqlite() {
let sqlite_err = rusqlite::Error::QueryReturnedNoRows;
let wallet_err: WalletError = sqlite_err.into();
match wallet_err {
WalletError::DatabaseError(msg) => assert!(!msg.is_empty()),
_ => panic!("Expected DatabaseError"),
}
}
#[test]
fn test_error_from_zip() {
let zip_err = zip::result::ZipError::FileNotFound;
let wallet_err: WalletError = zip_err.into();
match wallet_err {
WalletError::BackupError(msg) => assert!(!msg.is_empty()),
_ => panic!("Expected BackupError"),
}
}
}