use crate::core::app_errors::Result;
use async_trait::async_trait;
use tokio::io::{self, AsyncBufReadExt, AsyncWriteExt, BufReader};
#[async_trait(?Send)]
pub trait UserInterface {
async fn prompt(&mut self, message: &str) -> Result<String>;
async fn print(&mut self, message: &str) -> Result<()>;
}
#[doc(alias = "stdio")]
pub struct StdioInterface {
reader: BufReader<io::Stdin>,
}
impl Default for StdioInterface {
fn default() -> Self {
Self {
reader: BufReader::new(io::stdin()),
}
}
}
impl StdioInterface {
pub fn new() -> Self {
Self::default()
}
}
#[async_trait(?Send)]
impl UserInterface for StdioInterface {
async fn prompt(&mut self, message: &str) -> Result<String> {
let mut stdout = io::stdout();
stdout.write_all(message.as_bytes()).await?;
stdout.write_all(b"\n").await?;
stdout.flush().await?;
let mut line = String::new();
self.reader.read_line(&mut line).await?;
let line = line.trim_end_matches(&['\r', '\n'][..]).to_owned();
Ok(line)
}
async fn print(&mut self, message: &str) -> Result<()> {
let mut stdout = io::stdout();
stdout.write_all(message.as_bytes()).await?;
stdout.write_all(b"\n").await?;
stdout.flush().await?;
Ok(())
}
}