git_quick_add/ui/
select.rs

1use crate::models::path_items::PathItems;
2use dialoguer::MultiSelect;
3use std::process;
4
5/// Prompts the user to select files to stage and returns the selected file paths.
6/// If no files are selected, the program exits.
7/// # Arguments
8/// * `path_items` - A vector of PathItems representing files that can be staged.
9/// # Returns
10/// A vector of PathItems with updated selection status.
11pub fn choose_files(mut path_items: Vec<PathItems>) -> Vec<PathItems> {
12    let list_of_paths: Vec<String> = path_items.iter().map(|p| p.path.clone()).collect();
13    let list_of_preselected: Vec<bool> = path_items.iter().map(|p| p.is_staged).collect();
14
15    let selections = MultiSelect::new()
16        .with_prompt("Choose files to stage - (use Space to select - press Enter to submit)")
17        .items(list_of_paths)
18        .defaults(&list_of_preselected)
19        .interact()
20        .unwrap_or_else(|_| {
21            eprintln!("{}", console::style("Error selecting files").red());
22            process::exit(1)
23        });
24
25    for index in selections {
26        path_items[index].is_selected = true;
27    }
28
29    path_items
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35
36    #[test]
37    fn test_choose_files_selections() {
38        // This test is limited since it requires user interaction
39        // We can at least test the data structure transformations
40        let input = vec![
41            PathItems {
42                path: String::from("file1.txt"),
43                is_staged: true,
44                is_selected: false,
45            },
46            PathItems {
47                path: String::from("file2.txt"),
48                is_staged: false,
49                is_selected: false,
50            },
51        ];
52
53        let paths_clone = input.clone();
54        assert_eq!(
55            paths_clone
56                .iter()
57                .map(|p| p.is_selected)
58                .collect::<Vec<_>>(),
59            vec![false, false]
60        );
61    }
62}