tauri_plugin_biometric/
error.rs1use serde::{Serialize, ser::Serializer};
6
7pub type Result<T> = std::result::Result<T, Error>;
9
10#[derive(Debug, thiserror::Error)]
12pub enum Error {
13 #[error(transparent)]
15 Io(#[from] std::io::Error),
16 #[cfg(mobile)]
20 #[error(transparent)]
21 PluginInvoke(#[from] tauri::plugin::mobile::PluginInvokeError),
22 #[cfg(desktop)]
24 #[error("Biometric authentication failed: {message}")]
25 AuthenticationFailed {
26 message: String,
28 code: Option<String>,
30 },
31 #[cfg(desktop)]
33 #[error("Biometric unavailable: {message}")]
34 Unavailable {
35 message: String,
37 code: Option<String>,
39 },
40}
41
42impl Serialize for Error {
43 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
44 where
45 S: Serializer,
46 {
47 match self {
48 #[cfg(desktop)]
50 Self::AuthenticationFailed { message, code } | Self::Unavailable { message, code } => {
51 #[derive(Serialize)]
52 struct Payload<'a> {
53 message: &'a str,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 code: Option<&'a str>,
56 }
57 Payload {
58 message,
59 code: code.as_deref(),
60 }
61 .serialize(serializer)
62 }
63 _ => serializer.serialize_str(self.to_string().as_ref()),
64 }
65 }
66}
67
68#[cfg(all(test, desktop))]
69mod tests {
70 use super::Error;
71
72 #[test]
73 fn desktop_errors_serialize_like_mobile_rejections() {
74 let err = Error::AuthenticationFailed {
75 message: "Canceled by user.".into(),
76 code: Some("userCancel".into()),
77 };
78 assert_eq!(
79 serde_json::to_value(&err).unwrap(),
80 serde_json::json!({ "message": "Canceled by user.", "code": "userCancel" })
81 );
82
83 let err = Error::Unavailable {
84 message: "No biometry".into(),
85 code: None,
86 };
87 assert_eq!(
88 serde_json::to_value(&err).unwrap(),
89 serde_json::json!({ "message": "No biometry" })
90 );
91 }
92}