Add fetch_mod_info

This commit is contained in:
marceline-cramer 2021-11-21 20:50:55 -07:00
parent 2f088510ca
commit 4444e8aae8
3 changed files with 85 additions and 1 deletions

10
Cargo.lock generated
View File

@ -305,6 +305,7 @@ dependencies = [
"serde",
"serde_json",
"structopt",
"substring",
"tokio",
]
@ -940,6 +941,15 @@ dependencies = [
"syn",
]
[[package]]
name = "substring"
version = "1.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86"
dependencies = [
"autocfg",
]
[[package]]
name = "syn"
version = "1.0.81"

View File

@ -11,5 +11,6 @@ console = "0.15.0"
reqwest = { version = "0.11", features = ["json"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
substring = "1.4.5"
structopt = "0.3"
tokio = { version = "1", features = ["full"] }

View File

@ -2,6 +2,7 @@ use console::style;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use structopt::StructOpt;
use substring::Substring;
// TODO use ColoredHelp by default?
#[derive(StructOpt, Debug)]
@ -92,7 +93,7 @@ struct SearchResponse {
#[derive(Deserialize, Debug)]
struct ModResult {
mod_id: String,
mod_id: String, // TODO parse to `local-xxxxx` with regex
project_type: Option<String>, // NOTE this isn't in all search results?
author: String,
title: String,
@ -112,6 +113,33 @@ struct ModResult {
host: String,
}
#[derive(Deserialize, Debug)]
struct ModInfo {
id: String, // TODO serialize mod id?
slug: String,
team: String, // TODO serialize team id?
title: String,
description: String,
body: String,
published: String, // TODO serialize datetime
updated: String, // TODO serialize datetime
status: String,
// TODO License object
// license: String,
client_side: String, // TODO serialize as enum
server_side: String, // TODO serialize as enum
downloads: isize,
followers: isize,
categories: Vec<String>,
versions: Vec<String>,
icon_url: Option<String>,
issues_url: Option<String>,
source_url: Option<String>,
wiki_url: Option<String>,
discord_url: Option<String>,
donation_urls: Vec<String>,
}
impl ModResult {
fn format_info(&self) -> String {
let title = style(self.title.clone()).bold();
@ -165,9 +193,54 @@ fn display_search_results(config: &Config, response: &SearchResponse) {
}
}
// TODO implement enum for more graceful exiting
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(),
}
}
async fn fetch_mod_info(config: &Config, mod_result: &ModResult) -> anyhow::Result<ModInfo> {
let client = reqwest::Client::new();
let mod_id = &mod_result.mod_id;
let mod_id = mod_id.substring(6, mod_id.len()); // Remove "local-" prefix
let url = format!(
"https://{}/api/v1/mod/{}",
config.upstream.server_address, mod_id
);
let response = client.get(url).send().await?;
let response = response.json::<ModInfo>().await?;
Ok(response)
}
async fn cmd_get(config: &Config, package_name: String) -> anyhow::Result<()> {
let response = search_mods(config, package_name).await?;
if response.hits.is_empty() {
// TODO formatting
println!("No results; nothing to do...");
return Ok(());
}
display_search_results(config, &response);
let selected = select_from_results(config, &response).await;
if selected.is_empty() {
// TODO formatting
println!("No packages selected; nothing to do...");
return Ok(());
}
for to_get in selected.iter() {
let mod_info = fetch_mod_info(config, to_get).await?;
println!("mod: {:#?}", mod_info);
}
Ok(())
}