Skip to main content

Keychain

Struct Keychain 

Source
pub struct Keychain;
Expand description

Stateless entry point for generic-password keychain operations.

Implementations§

Source§

impl Keychain

Source

pub fn entry( account: impl Into<String>, service: impl Into<String>, ) -> KeychainEntry

Build a typed keychain entry for (account, service).

Source

pub fn set(account: &str, service: &str, password: &str) -> Result<()>

Upsert a generic-password keychain item.

§Errors

Returns an error if Security.framework rejects the item or the strings contain NUL bytes.

Examples found in repository?
examples/01_smoke.rs (line 8)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4    let account = "doom-fish-smoke";
5    let service = format!("doom-fish-smoke-test-{}", std::process::id());
6
7    let _ = Keychain::delete(account, &service);
8    Keychain::set(account, &service, "hunter2")?;
9
10    let value = Keychain::get(account, &service)?;
11    assert_eq!(value, "hunter2");
12
13    let accounts = Keychain::list_accounts(&service)?;
14    assert!(accounts.iter().any(|candidate| candidate == account));
15
16    Keychain::delete(account, &service)?;
17
18    let random = SecureRandom::bytes(32)?;
19    assert!(random.iter().any(|&byte| byte != 0));
20
21    println!("✅ security keychain + RNG OK");
22    Ok(())
23}
Source

pub fn get(account: &str, service: &str) -> Result<String>

Fetch a generic-password keychain item as UTF-8 text.

§Errors

Returns an error if the item does not exist, the stored bytes are not UTF-8, or Security.framework rejects the query.

Examples found in repository?
examples/01_smoke.rs (line 10)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4    let account = "doom-fish-smoke";
5    let service = format!("doom-fish-smoke-test-{}", std::process::id());
6
7    let _ = Keychain::delete(account, &service);
8    Keychain::set(account, &service, "hunter2")?;
9
10    let value = Keychain::get(account, &service)?;
11    assert_eq!(value, "hunter2");
12
13    let accounts = Keychain::list_accounts(&service)?;
14    assert!(accounts.iter().any(|candidate| candidate == account));
15
16    Keychain::delete(account, &service)?;
17
18    let random = SecureRandom::bytes(32)?;
19    assert!(random.iter().any(|&byte| byte != 0));
20
21    println!("✅ security keychain + RNG OK");
22    Ok(())
23}
Source

pub fn delete(account: &str, service: &str) -> Result<()>

Delete a generic-password keychain item.

Missing items are treated as success to make cleanup ergonomic.

§Errors

Returns an error if Security.framework rejects the delete request for another reason.

Examples found in repository?
examples/01_smoke.rs (line 7)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4    let account = "doom-fish-smoke";
5    let service = format!("doom-fish-smoke-test-{}", std::process::id());
6
7    let _ = Keychain::delete(account, &service);
8    Keychain::set(account, &service, "hunter2")?;
9
10    let value = Keychain::get(account, &service)?;
11    assert_eq!(value, "hunter2");
12
13    let accounts = Keychain::list_accounts(&service)?;
14    assert!(accounts.iter().any(|candidate| candidate == account));
15
16    Keychain::delete(account, &service)?;
17
18    let random = SecureRandom::bytes(32)?;
19    assert!(random.iter().any(|&byte| byte != 0));
20
21    println!("✅ security keychain + RNG OK");
22    Ok(())
23}
Source

pub fn list_accounts(service: &str) -> Result<Vec<String>>

List all account names for the given generic-password service.

§Errors

Returns an error if Security.framework rejects the query.

Examples found in repository?
examples/01_smoke.rs (line 13)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4    let account = "doom-fish-smoke";
5    let service = format!("doom-fish-smoke-test-{}", std::process::id());
6
7    let _ = Keychain::delete(account, &service);
8    Keychain::set(account, &service, "hunter2")?;
9
10    let value = Keychain::get(account, &service)?;
11    assert_eq!(value, "hunter2");
12
13    let accounts = Keychain::list_accounts(&service)?;
14    assert!(accounts.iter().any(|candidate| candidate == account));
15
16    Keychain::delete(account, &service)?;
17
18    let random = SecureRandom::bytes(32)?;
19    assert!(random.iter().any(|&byte| byte != 0));
20
21    println!("✅ security keychain + RNG OK");
22    Ok(())
23}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.