use std::collections::HashMap;
use std::fs;
use std::path::{Path, PathBuf};
use cargo_metadata::camino::Utf8PathBuf;
pub const CARGO_TEMPLATE_CONFIG_FILE_NAME: &str = "cargo-generate.toml";
pub const BAIZE_TEMPLATE_DIR: &str = ".template/";
pub const BAIZE_TEMPLATE_CONFIG_FILE_NAME: &str = "config.toml";
pub fn template_dir(base_dir: &Path) -> PathBuf {
base_dir.join(BAIZE_TEMPLATE_DIR)
}
pub fn config_file_path(base_dir: &Path) -> PathBuf {
base_dir.join(BAIZE_TEMPLATE_DIR).join(BAIZE_TEMPLATE_CONFIG_FILE_NAME)
}
#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct BaizeTemplateConfig {
pub name: String,
#[serde(default)]
pub destination: Utf8PathBuf,
pub init: bool,
}
#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct BaizeTemplate {
pub path: PathBuf,
pub config: BaizeTemplateConfig,
}
#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct BaizeConfig {
pub templates: HashMap<String, BaizeTemplate>,
}
pub fn locate_template_configs(base_dir: &Path) -> anyhow::Result<Vec<PathBuf>> {
let mut results = Vec::with_capacity(1);
if base_dir.is_dir() {
let mut paths_to_search_in = vec![base_dir.to_path_buf()];
'next_path: while let Some(path) = paths_to_search_in.pop() {
let mut sub_paths = vec![];
for entry in fs::read_dir(&path)? {
let entry = entry?;
let entry_path = entry.path();
if entry_path.is_dir() {
sub_paths.push(entry_path);
} else if entry.file_name() == CARGO_TEMPLATE_CONFIG_FILE_NAME {
results.push(path.strip_prefix(base_dir)?.to_path_buf());
continue 'next_path;
}
}
paths_to_search_in.append(&mut sub_paths);
}
} else {
results.push(base_dir.to_path_buf());
}
results.sort();
Ok(results)
}