use reqwest::Client;
use serde::Deserialize;
use std::collections::HashMap;
use std::error::Error;
#[derive(Debug, Deserialize)]
struct VersionMapping {
#[serde(flatten)]
versions: HashMap<String, String>,
}
pub async fn resolve_template_version(version: Option<&str>) -> Result<String, Box<dyn Error>> {
match version {
Some(v) => {
let mapping = fetch_all_versions().await?;
match mapping.versions.get(v) {
Some(commit) => {
println!("📌 Using rmk-template version {} (commit: {})", v, commit);
Ok(commit.clone())
}
None => {
let mut versions: Vec<String> = mapping.versions.keys().cloned().collect();
versions.sort();
Err(format!(
"Invalid version '{}'. Available versions: {}",
v,
versions.join(", ")
)
.into())
}
}
}
None => {
println!("📌 Using latest template from main branch");
Ok("main".to_string())
}
}
}
async fn fetch_all_versions() -> Result<VersionMapping, Box<dyn Error>> {
let config_url =
"https://raw.githubusercontent.com/HaoboGu/rmk-template/main/version-mapping.json";
let client = Client::new();
let response = client.get(config_url).send().await?;
if !response.status().is_success() {
return Err(format!("Failed to fetch version mapping: {}", response.status()).into());
}
let mapping: VersionMapping = response.json().await?;
Ok(mapping)
}
pub fn build_github_archive_url(user: &str, repo: &str, commit_or_branch: &str) -> String {
if commit_or_branch == "main" {
format!(
"https://github.com/{}/{}/archive/refs/heads/main.zip",
user, repo
)
} else {
format!(
"https://github.com/{}/{}/archive/{}.zip",
user, repo, commit_or_branch
)
}
}