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}