use std::path::PathBuf; use keyfork_pinentry::{ self, default_binary, ConfirmationDialog, MessageDialog, PassphraseInput, SecretString, }; #[derive(thiserror::Error, Debug)] pub enum PinentryError { #[error("No pinentry binary found")] NoPinentryFound, #[error("{0}")] Internal(#[from] keyfork_pinentry::Error), } pub type Result = std::result::Result; /// Display message dialogues, confirmation prompts, and passphrase inputs with keyfork-pinentry. pub struct PromptManager { program_title: String, pinentry_binary: PathBuf, } impl PromptManager { pub fn new( program_title: impl Into, pinentry_binary: impl Into>, ) -> Result { let path = match pinentry_binary.into() { Some(p) => p, None => default_binary()?, }; std::fs::metadata(&path).map_err(|_| PinentryError::NoPinentryFound)?; Ok(Self { program_title: program_title.into(), pinentry_binary: path, }) } #[allow(dead_code)] pub fn prompt_confirmation(&self, prompt: impl AsRef) -> Result { ConfirmationDialog::with_binary(self.pinentry_binary.clone()) .with_title(&self.program_title) .confirm(prompt.as_ref()) .map_err(|e| e.into()) } pub fn prompt_message(&self, prompt: impl AsRef) -> Result<()> { MessageDialog::with_binary(self.pinentry_binary.clone()) .with_title(&self.program_title) .show_message(prompt.as_ref()) .map_err(|e| e.into()) } pub fn prompt_passphrase( &self, prompt: impl AsRef, description: impl Into>, ) -> Result { match description.into() { Some(desc) => PassphraseInput::with_binary(self.pinentry_binary.clone()) .with_title(&self.program_title) .with_prompt(prompt.as_ref()) .with_description(&desc) .interact() .map_err(|e| e.into()), None => PassphraseInput::with_binary(self.pinentry_binary.clone()) .with_title(&self.program_title) .with_prompt(prompt.as_ref()) .interact() .map_err(|e| e.into()), } } }