use dialoguer::theme::ColorfulTheme;
use dialoguer::{FuzzySelect, MultiSelect};
use std::fmt::Display;
pub fn xbp_theme() -> ColorfulTheme {
ColorfulTheme::default()
}
pub fn searchable_select<T: Display>(
prompt: &str,
items: &[T],
default: usize,
) -> Result<Option<usize>, String> {
if items.is_empty() {
return Ok(None);
}
let default = default.min(items.len().saturating_sub(1));
FuzzySelect::with_theme(&xbp_theme())
.with_prompt(format!("{prompt} (type to search)"))
.items(items)
.default(default)
.interact_opt()
.map_err(|error| format!("Prompt failed: {error}"))
}
pub fn searchable_multi_select<T: Display>(
prompt: &str,
items: &[T],
defaults: &[bool],
) -> Result<Vec<usize>, String> {
if items.is_empty() {
return Ok(Vec::new());
}
let defaults = if defaults.len() == items.len() {
defaults.to_vec()
} else {
vec![false; items.len()]
};
MultiSelect::with_theme(&xbp_theme())
.with_prompt(format!("{prompt} (space to toggle, type to filter if supported)"))
.items(items)
.defaults(&defaults)
.interact()
.map_err(|error| format!("Prompt failed: {error}"))
}