use std::{error::Error, io::{self, Write, Read}};
use crossterm::{terminal::{self, ClearType}, cursor, event::{self, KeyEvent, KeyCode}};
use kdam::term::Colorizer;
use crate::Printable;
pub fn input(name: impl Into<String>, message: impl Into<String>) -> String {
"│ [dim_gray]ASKS ─·─► [magenda]{}[/]".print_with(vec![name.into()]);
"│ [dim_gray]╭─────╯[/]".print();
"│ [dim_gray]│ [/][yellow]{}[/]".print_with(vec![message.into()]);
"│ [dim_gray]╰─► [/]".print();
let mut input = String::new();
print!("{}", cursor::MoveUp(1).to_string());
print!("{}", cursor::MoveRight(5).to_string());
io::stdout().flush().unwrap();
io::stdin().read_line(&mut input).unwrap();
input.trim().to_string()
}
#[derive(Clone)]
pub struct Opt<T>
where
T: Clone,
{
option: String,
description: String,
action: fn() -> T,
}
impl<T> Opt<T>
where
T: Clone,
{
pub fn new(option: impl Into<String>, description: impl Into<String>, action: fn() -> T) -> Opt<T> {
Opt {
option: option.into(),
description: description.into(),
action: action,
}
}
}
pub fn selection<T>(options: Vec<Opt<T>>) -> T
where
T: Clone,
{
let mut selected_index = 0;
loop {
cursor::MoveTo(0, 0);
println!("Please select an option:");
for (i, opt) in options.iter().enumerate() {
if i == selected_index {
print!("\x1b[33m> \x1b[0m"); } else {
print!(" "); }
println!("{} - {}", opt.option, opt.description);
}
if event::poll(std::time::Duration::from_millis(100)).unwrap() {
if let event::Event::Key(KeyEvent { code, .. }) = event::read().unwrap() {
match code {
KeyCode::Up => {
if selected_index > 0 {
selected_index -= 1;
}
}
KeyCode::Down => {
if selected_index < options.len() - 1 {
selected_index += 1;
}
}
KeyCode::Enter => return (options[selected_index].action)(),
_ => {}
}
}
}
}
}