pub mod cutoff_tui;
pub mod stat_tui;
pub mod ui;
use std::io::{self, IsTerminal, Write};
pub fn tui_available() -> bool {
io::stdin().is_terminal() && io::stdout().is_terminal()
}
pub const TOOL: legume_tui::Tool = legume_tui::Tool::new("data-beans");
pub fn session_keys() -> Vec<(String, String)> {
legume_tui::help_keys()
.into_iter()
.map(|k| (k.key.to_lowercase(), k.short))
.collect()
}
pub fn session_help(lead: Option<&str>, more: &str) -> String {
let help = legume_tui::cli::SessionHelp::new()
.what_goes_on("the command goes on")
.resume_hint(Some(
"Starting it again starts a new one (naming the detached ones); \
`data-beans attach` with no name",
))
.more(more);
let help = match lead {
Some(lead) => help.lead(lead),
None => help,
};
legume_tui::cli::session_help(&TOOL, help)
}
#[derive(Debug, Clone)]
pub enum UserAction {
Proceed,
AdjustCutoffs(usize, usize),
Cancel,
}
pub fn prompt_user_action(
current_row_cutoff: usize,
current_col_cutoff: usize,
) -> anyhow::Result<UserAction> {
println!("\nOptions:");
println!(" [p] Proceed with current cutoffs");
println!(" [a] Adjust cutoffs");
println!(" [c] Cancel");
print!("\nChoose an option (p/a/c): ");
io::stdout().flush()?;
let mut input = String::new();
io::stdin().read_line(&mut input)?;
let choice = input.trim().to_lowercase();
match choice.as_str() {
"p" | "proceed" | "y" | "yes" => Ok(UserAction::Proceed),
"c" | "cancel" | "n" | "no" => Ok(UserAction::Cancel),
"a" | "adjust" => {
let new_row_cutoff = prompt_cutoff_value("row", current_row_cutoff)?;
let new_col_cutoff = prompt_cutoff_value("column", current_col_cutoff)?;
Ok(UserAction::AdjustCutoffs(new_row_cutoff, new_col_cutoff))
}
_ => {
println!("Invalid choice. Cancelling operation.");
Ok(UserAction::Cancel)
}
}
}
fn prompt_cutoff_value(label: &str, current: usize) -> anyhow::Result<usize> {
print!("\nEnter new {} nnz cutoff (current: {}): ", label, current);
io::stdout().flush()?;
let mut input = String::new();
io::stdin().read_line(&mut input)?;
let value = input.trim().parse::<usize>().unwrap_or(current);
Ok(value)
}
pub fn confirm(message: &str) -> anyhow::Result<bool> {
print!("{} (y/n): ", message);
io::stdout().flush()?;
let mut input = String::new();
io::stdin().read_line(&mut input)?;
let choice = input.trim().to_lowercase();
Ok(matches!(choice.as_str(), "y" | "yes"))
}
#[cfg(test)]
#[path = "tests/session.rs"]
mod tests;