novel_api/common/utils/
keyring.rs1use keyring::Entry;
2use zeroize::Zeroize;
3
4use crate::Error;
5
6#[must_use]
8pub struct Keyring {
9 entry: Entry,
10}
11
12impl Keyring {
13 pub fn new<T, E>(app_name: T, username: E) -> Result<Self, Error>
15 where
16 T: AsRef<str>,
17 E: AsRef<str>,
18 {
19 let service = format!("novel-rs-{}", app_name.as_ref());
20 let entry = Entry::new(&service, username.as_ref())?;
21
22 Ok(Self { entry })
23 }
24
25 pub fn get_password(&self) -> Result<String, Error> {
27 Ok(self.entry.get_password()?)
28 }
29
30 pub fn set_password(&self, mut password: String) -> Result<(), Error> {
32 self.entry.set_password(&password)?;
33 password.zeroize();
34 Ok(())
35 }
36
37 pub fn delete_password(&self) -> Result<(), Error> {
39 Ok(self.entry.delete_credential()?)
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use pretty_assertions::assert_eq;
46
47 use super::*;
48
49 #[tokio::test]
50 async fn keyring() -> Result<(), Error> {
51 let keyring = Keyring::new("test-app", "user-name")?;
52 let password = "test-password".to_string();
53
54 keyring.set_password(password.clone())?;
55 assert_eq!(keyring.get_password()?, password);
56
57 keyring.delete_password()?;
58
59 Ok(())
60 }
61}