1use std::io;
7
8use thiserror::Error;
9
10pub type Result<T> = std::result::Result<T, Error>;
12
13#[derive(Error, Debug)]
18pub enum Error {
19 #[error("Storage error: {0}")]
21 Storage(String),
22
23 #[error("Configuration error: {0}")]
25 Config(String),
26
27 #[error("UHID error: {0}")]
29 Uhid(String),
30
31 #[error("Credential management error: {0}")]
33 CredentialManagement(String),
34
35 #[error("User verification failed: {0}")]
37 UserVerificationFailed(String),
38
39 #[error("Operation cancelled by user")]
41 Cancelled,
42
43 #[error("IO error: {0}")]
45 Io(#[from] io::Error),
46
47 #[error("Serialization error: {0}")]
49 Serialization(String),
50
51 #[error("Invalid data: {0}")]
53 InvalidData(String),
54
55 #[error("{0}")]
57 Other(String),
58}
59
60impl Error {
61 pub fn format_cli(&self) -> String {
65 match self {
66 Error::Storage(msg) => format!("Storage error: {}", msg),
67 Error::Config(msg) => format!("Configuration error: {}", msg),
68 Error::Uhid(msg) => format!("UHID error: {}", msg),
69 Error::CredentialManagement(msg) => format!("Credential management error: {}", msg),
70 Error::UserVerificationFailed(msg) => format!("User verification failed: {}", msg),
71 Error::Cancelled => "Operation cancelled by user".to_string(),
72 Error::Io(err) => format!("IO error: {}", err),
73 Error::Serialization(msg) => format!("Serialization error: {}", msg),
74 Error::InvalidData(msg) => format!("Invalid data: {}", msg),
75 Error::Other(msg) => msg.clone(),
76 }
77 }
78}
79
80impl From<soft_fido2::Error> for Error {
82 fn from(err: soft_fido2::Error) -> Self {
83 Error::CredentialManagement(format!("{:?}", err))
84 }
85}
86
87impl From<Error> for soft_fido2::Error {
89 fn from(err: Error) -> Self {
90 match err {
91 Error::Storage(ref msg) if msg.contains("not found") => soft_fido2::Error::DoesNotExist,
92 Error::Storage(ref msg) if msg.contains("No more credentials") => {
93 soft_fido2::Error::DoesNotExist
94 }
95 _ => soft_fido2::Error::Other,
96 }
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn test_soft_fido2_error_conversion() {
106 let err: Error = soft_fido2::Error::DoesNotExist.into();
107 assert!(matches!(err, Error::CredentialManagement(_)));
108
109 let err: soft_fido2::Error = Error::Storage("not found".to_string()).into();
110 assert!(matches!(err, soft_fido2::Error::DoesNotExist));
111 }
112}