use std::{collections::HashMap, fs::File, io::Read, path::Path};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JunoToml {
pub schema: u8,
pub vars: HashMap<String, String>,
pub project: JunoPackageMetadata,
#[serde(rename = "lib")]
pub libs: Vec<JunoPackageLib>,
#[serde(rename = "bin")]
pub bins: Vec<JunoPackageBin>,
#[serde(rename = "dep")]
pub dependencies: HashMap<String, JunoDependency>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JunoPackageMetadata {
pub name: String,
pub version: String,
pub edition: String,
pub description: String,
pub license: String,
pub homepage: String,
pub repository: String,
pub documentation: String,
pub authors: Vec<String>,
pub keywords: Vec<String>,
pub categories: Vec<String>,
pub readme: String,
pub publish: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JunoPackageLib {
pub entry: String,
pub output: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JunoPackageBin {
pub entry: String,
pub output: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JunoDependency {
pub authority: String,
pub namespace: String,
#[serde(skip)]
pub name: String,
pub version: String,
pub hash: Option<String>,
pub sign: Option<String>,
}
pub fn parse_juno_toml(path: &Path) -> anyhow::Result<JunoToml> {
let buf: &mut String = &mut String::new();
File::open(path)?.read_to_string(buf)?;
let mut juno_toml: JunoToml = toml::from_str(buf)?;
juno_toml.resolve_vars();
Ok(juno_toml)
}
impl JunoToml {
pub fn resolve_vars(&mut self) {
self.project.name = replace_vars(&self.project.name, &self.vars);
self.project.version = replace_vars(&self.project.version, &self.vars);
self.project.description = replace_vars(&self.project.description, &self.vars);
self.project.license = replace_vars(&self.project.license, &self.vars);
self.project.homepage = replace_vars(&self.project.homepage, &self.vars);
self.project.repository = replace_vars(&self.project.repository, &self.vars);
self.project.documentation = replace_vars(&self.project.documentation, &self.vars);
self.project.readme = replace_vars(&self.project.readme, &self.vars);
for lib in &mut self.libs {
lib.entry = replace_vars(&lib.entry, &self.vars);
lib.output = replace_vars(&lib.output, &self.vars);
}
for bin in &mut self.bins {
bin.entry = replace_vars(&bin.entry, &self.vars);
bin.output = replace_vars(&bin.output, &self.vars);
}
for (dep_name, dep) in &mut self.dependencies {
dep.authority = replace_vars(&dep.authority, &self.vars);
dep.namespace = replace_vars(&dep.namespace, &self.vars);
dep.name = dep_name.clone();
dep.version = replace_vars(&dep.version, &self.vars);
if let Some(hash) = dep.hash.as_ref() {
dep.hash = Some(replace_vars(hash, &self.vars));
}
if let Some(sign) = dep.sign.as_ref() {
dep.sign = Some(replace_vars(sign, &self.vars));
}
}
for author in &mut self.project.authors {
*author = replace_vars(author, &self.vars);
}
for keyword in &mut self.project.keywords {
*keyword = replace_vars(keyword, &self.vars);
}
for category in &mut self.project.categories {
*category = replace_vars(category, &self.vars);
}
}
}
fn replace_vars(input: &str, vars: &HashMap<String, String>) -> String {
let mut output = input.to_string();
for (key, value) in vars {
output = output.replace(&format!("${{{}}}", key), value);
}
output
}