diff --git a/index.d.ts b/index.d.ts index bf3a658..34a95da 100644 --- a/index.d.ts +++ b/index.d.ts @@ -36,7 +36,7 @@ export declare class AsyncEntry { /** * Retrieve the password saved for this entry. * - * Returns a [NoEntry](Error::NoEntry) error if there isn't one. + * Returns no password if there isn't one. * * Can return an [Ambiguous](Error::Ambiguous) error * if there is more than one platform credential @@ -113,7 +113,7 @@ export declare class Entry { /** * Retrieve the password saved for this entry. * - * Returns a [NoEntry](Error::NoEntry) error if there isn't one. + * Returns no password if there isn't one. * * Can return an [Ambiguous](Error::Ambiguous) error * if there is more than one platform credential diff --git a/src/async_entry.rs b/src/async_entry.rs index f9313a8..494d38e 100644 --- a/src/async_entry.rs +++ b/src/async_entry.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use napi::bindgen_prelude::*; use napi_derive::napi; +use crate::entry::into_optional_password; #[cfg(target_os = "linux")] use crate::linux_credential_builder::LinuxCredentialBuilder; @@ -161,7 +162,7 @@ impl AsyncEntry { #[napi(ts_return_type = "Promise")] /// Retrieve the password saved for this entry. /// - /// Returns a [NoEntry](Error::NoEntry) error if there isn't one. + /// Returns no password if there isn't one. /// /// Can return an [Ambiguous](Error::Ambiguous) error /// if there is more than one platform credential @@ -250,7 +251,7 @@ impl Task for PasswordTask { type JsValue = Option; fn compute(&mut self) -> Result { - Ok(self.inner.get_password().ok()) + into_optional_password(self.inner.get_password()) } fn resolve(&mut self, _env: Env, output: Self::Output) -> Result { diff --git a/src/entry.rs b/src/entry.rs index 2b61969..55c5343 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -4,6 +4,16 @@ use napi_derive::napi; #[cfg(target_os = "linux")] use crate::linux_credential_builder::LinuxCredentialBuilder; +pub(crate) fn into_optional_password( + result: keyring_core::Result, +) -> Result> { + match result { + Ok(password) => Ok(Some(password)), + Err(keyring_core::Error::NoEntry) => Ok(None), + Err(error) => Err(anyhow::Error::from(error).into()), + } +} + #[napi] pub struct Entry { inner: keyring_core::Entry, @@ -146,15 +156,15 @@ impl Entry { #[napi] /// Retrieve the password saved for this entry. /// - /// Returns a [NoEntry](Error::NoEntry) error if there isn't one. + /// Returns no password if there isn't one. /// /// Can return an [Ambiguous](Error::Ambiguous) error /// if there is more than one platform credential /// that matches this entry. This can only happen /// on some platforms, and then only if a third-party /// application wrote the ambiguous credential. - pub fn get_password(&self) -> Option { - self.inner.get_password().ok() + pub fn get_password(&self) -> Result> { + into_optional_password(self.inner.get_password()) } #[napi] @@ -200,6 +210,36 @@ impl Entry { } } +#[cfg(test)] +mod tests { + use super::into_optional_password; + + #[test] + fn returns_password_when_found() { + assert_eq!( + into_optional_password(Ok("password".to_string())).unwrap(), + Some("password".to_string()) + ); + } + + #[test] + fn returns_none_when_password_is_missing() { + assert_eq!( + into_optional_password(Err(keyring_core::Error::NoEntry)).unwrap(), + None + ); + } + + #[test] + fn preserves_non_missing_errors() { + let result = into_optional_password(Err(keyring_core::Error::NoStorageAccess(Box::new( + std::io::Error::other("keychain is locked"), + )))); + + assert!(result.is_err()); + } +} + #[napi(object)] pub struct Credential { pub account: String,