use std::io;
use crate::Callbacks;
mod error;
pub use error::ReadError;
pub mod file_io;
mod identities;
pub use identities::read_identities;
mod recipients;
pub use recipients::read_recipients;
pub struct StdinGuard {
stdin_used: bool,
}
impl StdinGuard {
pub fn new(input_is_stdin: bool) -> Self {
Self {
stdin_used: input_is_stdin,
}
}
fn open(&mut self, filename: String) -> Result<file_io::InputReader, ReadError> {
let input = file_io::InputReader::new(Some(filename))?;
if matches!(input, file_io::InputReader::Stdin(_)) {
if self.stdin_used {
return Err(ReadError::MultipleStdin);
}
self.stdin_used = true;
}
Ok(input)
}
}
#[derive(Clone, Copy)]
pub struct UiCallbacks;
impl Callbacks for UiCallbacks {
fn display_message(&self, message: &str) {
eprintln!("{}", message);
}
fn confirm(&self, message: &str, yes_string: &str, no_string: Option<&str>) -> Option<bool> {
#[cfg(feature = "console")]
{
let term = console::Term::stderr();
let cancel_str = no_string.unwrap_or("no");
let initial = format!("{}: ({}/{}) ", message, yes_string, cancel_str);
loop {
term.write_str(&initial).ok()?;
let response = term.read_line().ok()?.to_lowercase();
if ["y", "yes"].contains(&response.as_str())
|| response == yes_string.to_lowercase()
{
break Some(true);
} else if ["n", "no"].contains(&response.as_str())
|| Some(response.as_str()) == no_string.map(|s| s.to_lowercase()).as_deref()
{
break Some(false);
}
}
}
#[cfg(not(feature = "console"))]
{
let _ = (message, yes_string, no_string);
None
}
}
fn request_public_string(&self, description: &str) -> Option<String> {
#[cfg(feature = "console")]
{
let term = console::Term::stderr();
term.write_str(description).ok()?;
term.read_line().ok().filter(|s| !s.is_empty())
}
#[cfg(not(feature = "console"))]
{
let _ = description;
None
}
}
fn request_passphrase(&self, _description: &str) -> Option<anubis_core::secrecy::SecretString> {
None
}
}