use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct SelectorItem {
pub label: String,
pub value: String,
pub description: Option<String>,
}
impl SelectorItem {
pub fn new(label: impl Into<String>, value: impl Into<String>) -> Self {
Self { label: label.into(), value: value.into(), description: None }
}
pub fn with_description(
label: impl Into<String>,
value: impl Into<String>,
description: impl Into<String>,
) -> Self {
Self {
label: label.into(),
value: value.into(),
description: Some(description.into()),
}
}
}
#[derive(Debug, Clone, Default)]
pub struct SelectorOptions {
pub prompt: String,
pub fuzzy: bool,
pub default: Option<usize>,
pub allow_cancel: bool,
}
impl SelectorOptions {
pub fn new(prompt: impl Into<String>) -> Self {
Self {
prompt: prompt.into(),
fuzzy: true, default: Some(0),
allow_cancel: true,
}
}
pub fn with_fuzzy(mut self, fuzzy: bool) -> Self {
self.fuzzy = fuzzy;
self
}
pub fn with_default(mut self, index: usize) -> Self {
self.default = Some(index);
self
}
}
pub type SelectorCallback =
Arc<dyn Fn(&[SelectorItem], &SelectorOptions) -> Option<String> + Send + Sync>;
pub fn noop_selector(
_items: &[SelectorItem],
_options: &SelectorOptions,
) -> Option<String> {
None
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_selector_item_new() {
let item = SelectorItem::new("Label", "value");
assert_eq!(item.label, "Label");
assert_eq!(item.value, "value");
assert!(item.description.is_none());
}
#[test]
fn test_selector_item_with_description() {
let item = SelectorItem::with_description("Label", "value", "A description");
assert_eq!(item.label, "Label");
assert_eq!(item.value, "value");
assert_eq!(item.description, Some("A description".to_string()));
}
#[test]
fn test_selector_options_defaults() {
let opts = SelectorOptions::new("Select an item");
assert_eq!(opts.prompt, "Select an item");
assert!(opts.fuzzy);
assert_eq!(opts.default, Some(0));
assert!(opts.allow_cancel);
}
#[test]
fn test_selector_options_with_fuzzy() {
let opts = SelectorOptions::new("Select").with_fuzzy(false);
assert!(!opts.fuzzy);
}
#[test]
fn test_selector_options_with_default() {
let opts = SelectorOptions::new("Select").with_default(5);
assert_eq!(opts.default, Some(5));
}
#[test]
fn test_noop_selector() {
let items = vec![
SelectorItem::new("Item 1", "val1"),
SelectorItem::new("Item 2", "val2"),
];
let opts = SelectorOptions::new("Select");
assert_eq!(noop_selector(&items, &opts), None);
}
#[test]
fn test_selector_callback_type() {
let callback: SelectorCallback = Arc::new(|items, _opts| {
items.first().map(|i| i.value.clone())
});
let items = vec![SelectorItem::new("First", "first_value")];
let opts = SelectorOptions::new("Test");
let result = callback(&items, &opts);
assert_eq!(result, Some("first_value".to_string()));
}
}