io_keyring/coroutines/
read.rs1use log::trace;
4use secrecy::SecretString;
5use thiserror::Error;
6
7use crate::{entry::KeyringEntry, io::KeyringIo};
8
9#[derive(Clone, Debug, Error)]
11pub enum ReadSecretError {
12 #[error("Invalid argument: expected {0}, got {1:?}")]
18 InvalidArgument(&'static str, KeyringIo),
19
20 #[error("Entry not ready")]
22 NotReady,
23}
24
25#[derive(Clone, Debug)]
27pub enum ReadSecretResult {
28 Ok(SecretString),
30
31 Io(KeyringIo),
33
34 Err(ReadSecretError),
36}
37
38#[derive(Clone, Debug)]
40pub struct ReadSecret {
41 entry: Option<KeyringEntry>,
42}
43
44impl ReadSecret {
45 pub fn new(entry: KeyringEntry) -> Self {
47 Self { entry: Some(entry) }
48 }
49
50 pub fn resume(&mut self, arg: Option<KeyringIo>) -> ReadSecretResult {
52 let Some(arg) = arg else {
53 let Some(entry) = self.entry.take() else {
54 return ReadSecretResult::Err(ReadSecretError::NotReady);
55 };
56
57 trace!("need I/O to read secret from keyring entry");
58 return ReadSecretResult::Io(KeyringIo::Read(Err(entry)));
59 };
60
61 let KeyringIo::Read(io) = arg else {
62 return ReadSecretResult::Err(ReadSecretError::InvalidArgument("read output", arg));
63 };
64
65 let secret = match io {
66 Ok(secret) => secret,
67 Err(entry) => return ReadSecretResult::Io(KeyringIo::Read(Err(entry))),
68 };
69
70 trace!("resume after reading keyring entry");
71 ReadSecretResult::Ok(secret)
72 }
73}