Multiselect results

This commit is contained in:
marceline-cramer 2021-11-29 12:30:30 -07:00
parent 5c1e8e15cc
commit f58d25b54b
3 changed files with 46 additions and 6 deletions

19
Cargo.lock generated
View File

@ -133,6 +133,18 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]]
name = "dialoguer"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61579ada4ec0c6031cfac3f86fdba0d195a7ebeb5e36693bd53cb5999a25beeb"
dependencies = [
"console",
"lazy_static",
"tempfile",
"zeroize",
]
[[package]]
name = "directories"
version = "2.0.2"
@ -301,6 +313,7 @@ dependencies = [
"anyhow",
"confy",
"console",
"dialoguer",
"reqwest",
"serde",
"serde_json",
@ -1280,3 +1293,9 @@ checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
dependencies = [
"winapi",
]
[[package]]
name = "zeroize"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619"

View File

@ -8,6 +8,7 @@ edition = "2021"
anyhow = "1.0"
confy = "0.4"
console = "0.15.0"
dialoguer = "0.9.0"
reqwest = { version = "0.11", features = ["json"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"

View File

@ -224,12 +224,32 @@ fn display_search_results(config: &Config, response: &SearchResponse) {
async fn select_from_results<'a>(
_config: &Config,
response: &'a SearchResponse,
) -> Vec<&'a ModResult> {
// TODO actually select with a dialogue
match response.hits.first() {
Some(first) => vec![first],
None => Vec::new(),
) -> anyhow::Result<Vec<&'a ModResult>> {
let input: String = dialoguer::Input::new()
.with_prompt("Mods to install (eg: 1 2 3)")
.interact_text()?;
let mut selected: Vec<usize> = Vec::new();
for token in input.split(" ") {
// TODO range input (eg: 1-3)
let index: usize = token.parse().expect("Token must be an integer");
if index < 1 || index > response.hits.len() {
// TODO return useful error instead of panicking
panic!("Index {} is out of bounds", index);
}
// input is indexed from 1, but results are indexed from 0
let index = index - 1;
if !selected.contains(&index) {
selected.push(index);
} else {
// TODO make this a proper warning log message
println!("warning: repeated index {}", index);
}
}
Ok(selected.iter().map(|i| &response.hits[*i]).collect())
}
async fn fetch_mod_info(config: &Config, mod_result: &ModResult) -> anyhow::Result<ModInfo> {
@ -282,7 +302,7 @@ async fn cmd_get(config: &Config, package_name: String) -> anyhow::Result<()> {
}
display_search_results(config, &response);
let selected = select_from_results(config, &response).await;
let selected = select_from_results(config, &response).await?;
if selected.is_empty() {
// TODO formatting