keyfork/crates/util/keyfork-prompt/src/lib.rs

107 lines
3.9 KiB
Rust

//! Prompt display and interaction management.
use std::borrow::Borrow;
#[cfg(feature = "mnemonic")]
use keyfork_mnemonic_util::Wordlist;
///
pub mod terminal;
pub mod validators;
pub use terminal::{Terminal, DefaultTerminal, default_terminal};
/// An error occurred while displaying a prompt.
#[derive(thiserror::Error, Debug)]
pub enum Error {
/// The given handler is not a TTY and can't be used to display prompts.
#[error("The given handler is not a TTY")]
NotATTY,
/// Validating user input failed.
#[error("Validation of the input failed after {0} retries (last error: {1})")]
Validation(u8, String),
/// A ctrl-c interrupt was caught by the handler.
#[error("User pressed ctrl-c, terminating the session")]
CtrlC,
/// An error occurred while interacting with a terminal.
#[error("IO Error: {0}")]
IO(#[from] std::io::Error),
}
#[allow(missing_docs)]
pub type Result<T, E = Error> = std::result::Result<T, E>;
/// A message displayed by [`PromptHandler::prompt_message`].
pub enum Message {
/// A textual message, wrapping at space boundaries when reaching the end of the terminal.
Text(String),
/// A data message, with no word wrapping, and automatic hiding of the message when a terminal
/// is too small.
Data(String),
}
/// A trait to allow displaying prompts and accepting input.
pub trait PromptHandler {
/// Prompt the user for input.
///
/// # Errors
/// The method may return an error if the message was not able to be displayed or if the input
/// could not be read.
fn prompt_input(&mut self, prompt: &str) -> Result<String>;
/// Prompt the user for input based on a wordlist. A language must be specified as the generic
/// parameter `X` (any type implementing [`Wordlist`]) when parsing a wordlist.
///
/// # Errors
/// The method may return an error if the message was not able to be displayed or if the input
/// could not be read.
#[cfg(feature = "mnemonic")]
fn prompt_wordlist<X>(&mut self, prompt: &str) -> Result<String> where X: Wordlist;
/// Prompt the user for input based on a wordlist, while validating the wordlist using a
/// provided parser function, returning the type from the parser. A language must be specified
/// as the generic parameter `X` (any type implementing [`Wordlist`]) when parsing a wordlist.
///
/// # Errors
/// The method may return an error if the message was not able to be displayed, if the input
/// could not be read, or if the parser returned an error.
#[cfg(feature = "mnemonic")]
fn prompt_validated_wordlist<X, V>(
&mut self,
prompt: &str,
retries: u8,
validator_fn: impl Fn(String) -> Result<V, Box<dyn std::error::Error>>,
) -> Result<V, Error>
where
X: Wordlist;
/// Prompt the user for a passphrase, which is hidden while typing.
///
/// # Errors
/// The method may return an error if the message was not able to be displayed or if the input
/// could not be read.
fn prompt_passphrase(&mut self, prompt: &str) -> Result<String>;
/// Prompt the user for a passphrase, which is hidden while typing, and validate the passphrase
/// using a provided parser function, returning the type from the parser.
///
/// # Errors
/// The method may return an error if the message was not able to be displayed, if the input
/// could not be read, or if the parser returned an error.
fn prompt_validated_passphrase<V>(
&mut self,
prompt: &str,
retries: u8,
validator_fn: impl Fn(String) -> Result<V, Box<dyn std::error::Error>>,
) -> Result<V, Error>;
/// Prompt the user with a [`Message`].
///
/// # Errors
/// The method may return an error if the message was not able to be displayed or if an error
/// occurred while waiting for the user to dismiss the message.
fn prompt_message(&mut self, prompt: impl Borrow<Message>) -> Result<()>;
}