Download crates/forge_select/src/multi.rs from SaylorTwift/forgecode: direct link, hf CLI and curl.
- Browser
- Download file 2.3 kB
-
https://huggingface.co/SaylorTwift/forgecode/resolve/main/crates/forge_select/src/multi.rs
- Command line
-
hf download hf://SaylorTwift/forgecode/crates/forge_select/src/multi.rs
-
curl -L -o multi.rs https://huggingface.co/SaylorTwift/forgecode/resolve/main/crates/forge_select/src/multi.rs
2.3 kB
| use std::io::IsTerminal; | |
| use anyhow::Result; | |
| use console::strip_ansi_codes; | |
| use crate::preview::{SelectMode, SelectRow, SelectUiOptions}; | |
| /// Builder for multi-select prompts. | |
| pub struct MultiSelectBuilder<T> { | |
| pub(crate) message: String, | |
| pub(crate) options: Vec<T>, | |
| } | |
| impl<T> MultiSelectBuilder<T> { | |
| /// Execute multi-select prompt. | |
| /// | |
| /// # Returns | |
| /// | |
| /// - `Ok(Some(Vec<T>))` when the user selects one or more options. | |
| /// - `Ok(None)` when no options are available or the user cancels. | |
| /// | |
| /// # Errors | |
| /// | |
| /// Returns an error if terminal setup, event handling, or rendering fails. | |
| pub fn prompt(self) -> Result<Option<Vec<T>>> | |
| where | |
| T: std::fmt::Display + Clone, | |
| { | |
| if !std::io::stderr().is_terminal() { | |
| return Ok(None); | |
| } | |
| if self.options.is_empty() { | |
| return Ok(None); | |
| } | |
| let rows = self | |
| .options | |
| .iter() | |
| .enumerate() | |
| .map(|(index, item)| { | |
| let display = strip_ansi_codes(&item.to_string()).trim().to_string(); | |
| SelectRow::new(index.to_string(), display.clone()).search(display) | |
| }) | |
| .collect::<Vec<_>>(); | |
| let selected = SelectUiOptions::new(format!("{} ❯ ", self.message), rows) | |
| .mode(SelectMode::Multi) | |
| .prompt_multi()?; | |
| Ok(selected.and_then(|rows| { | |
| let selected_items = rows | |
| .into_iter() | |
| .filter_map(|row| { | |
| row.raw | |
| .parse::<usize>() | |
| .ok() | |
| .and_then(|index| self.options.get(index).cloned()) | |
| }) | |
| .collect::<Vec<_>>(); | |
| if selected_items.is_empty() { | |
| None | |
| } else { | |
| Some(selected_items) | |
| } | |
| })) | |
| } | |
| } | |
| mod tests { | |
| use pretty_assertions::assert_eq; | |
| use crate::ForgeWidget; | |
| fn test_multi_select_builder_creates() { | |
| let builder = ForgeWidget::multi_select("Select options:", vec!["a", "b", "c"]); | |
| assert_eq!(builder.message, "Select options:"); | |
| assert_eq!(builder.options, vec!["a", "b", "c"]); | |
| } | |
| } | |