archetect_core/
input.rs

1use crate::config::{Catalog, CatalogEntry, CatalogError};
2
3use crate::source::{Source};
4use crate::Archetect;
5use crate::vendor::read_input::shortcut::input;
6use crate::vendor::read_input::InputBuild;
7use std::collections::{HashMap, HashSet};
8
9pub fn you_are_sure(message: &str) -> bool {
10    input::<bool>()
11        .prompting_on_stderr()
12        .msg(format!("{} [false]: ", message))
13        .default(false)
14        .get()
15}
16
17pub fn select_from_catalog(
18    archetect: &Archetect,
19    catalog: &Catalog,
20    current_source: &Source,
21) -> Result<CatalogEntry, CatalogError> {
22    let mut catalog = catalog.clone();
23    let mut current_source = current_source.clone();
24
25    loop {
26        if catalog.entries().is_empty() {
27            return Err(CatalogError::EmptyCatalog);
28        }
29
30        let choice = select_from_entries(archetect, catalog.entries_owned())?;
31
32        match choice {
33            CatalogEntry::Catalog { description: _, source } => {
34                let source = Source::detect(archetect, &source, Some(current_source))?;
35                current_source = source.clone();
36                catalog = Catalog::load(source)?;
37            }
38            CatalogEntry::Archetype {
39                description: _,
40                source: _,
41            } => {
42                return Ok(choice);
43            }
44            CatalogEntry::Group {
45                description: _,
46                entries: _,
47            } => unreachable!(),
48        }
49    }
50}
51
52pub fn select_from_entries(
53    _archetect: &Archetect,
54    mut entry_items: Vec<CatalogEntry>,
55) -> Result<CatalogEntry, CatalogError> {
56    if entry_items.is_empty() {
57        return Err(CatalogError::EmptyGroup);
58    }
59
60    loop {
61        let mut choices = entry_items
62            .iter()
63            .enumerate()
64            .map(|(id, entry)| (id + 1, entry.clone()))
65            .collect::<HashMap<_, _>>();
66
67        for (id, entry) in entry_items.iter().enumerate() {
68            eprintln!("{:>2}) {}", id + 1, entry.description());
69        }
70
71        let test_values = choices.keys().map(|v| *v).collect::<HashSet<_>>();
72        let result = input::<usize>()
73            .prompting_on_stderr()
74            .msg("\nSelect an entry: ")
75            .add_test(move |value| test_values.contains(value))
76            .err("Please enter the number of a selection from the list.")
77            .repeat_msg("Select an entry: ")
78            .get();
79
80        let choice = choices.remove(&result).unwrap();
81
82        match choice {
83            CatalogEntry::Group {
84                description: _,
85                entries,
86            } => {
87                entry_items = entries;
88            }
89            CatalogEntry::Catalog {
90                description: _,
91                source: _,
92            } => return Ok(choice),
93            CatalogEntry::Archetype {
94                description: _,
95                source: _,
96            } => return Ok(choice),
97        }
98    }
99}