use super::dirs::DirCfg;
use crate::error::WefterErr;
use anyhow::{Result, anyhow};
use std::collections::hash_map::HashMap;
use std::fs;
use std::path::PathBuf;
const INIT_LUA_FILE: &str = "init.lua";
const AUTO_LUA_FILE: &str = "auto.lua";
const TEMPLATE_FOLDER_DIR: &str = "templates";
#[derive(Debug, Clone)]
pub struct ResourceDir {
pub path: PathBuf,
pub init: PathBuf,
pub auto: Option<PathBuf>,
pub templates: PathBuf,
}
pub type ResourceDirTable = HashMap<String, ResourceDir>;
impl ResourceDir {
fn new(dir: PathBuf) -> Result<(String, ResourceDir)> {
let mut luainit = dir.clone();
luainit.push(INIT_LUA_FILE);
if !luainit.is_file() {
return Err(WefterErr::InvalidResource(luainit).into());
}
let mut templates = dir.clone();
templates.push(TEMPLATE_FOLDER_DIR);
if !templates.is_dir() {
fs::create_dir(&templates)?;
log::debug!("Created template directory: {:?}", &templates);
}
let mut auto = dir.clone();
auto.push(AUTO_LUA_FILE);
let profile = String::from(
dir.file_name()
.and_then(|os| os.to_str())
.ok_or(anyhow!("Cannot cast {:?} into String", &dir))?,
);
let item = Self {
path: dir,
init: luainit,
templates,
auto: if auto.is_file() { Some(auto) } else { None },
};
Ok((profile, item))
}
pub fn load(dirs: &DirCfg) -> Result<ResourceDirTable> {
let mut resources = HashMap::new();
if let Some(localdir) = &dirs.local {
for entry in fs::read_dir(localdir)? {
let path = entry?.path();
if path.is_dir() {
log::trace!("Found resource (local): {:?}", &path);
let (profile, res) = Self::new(path)?;
log::trace!("Registered profile '{}' (local): {:?}", &profile, &res);
resources.insert(profile, res);
}
}
}
for entry in fs::read_dir(&dirs.data)? {
let path = entry?.path();
if path.is_dir() {
log::trace!("Found resource (system): {:?}", &path);
let (profile, res) = Self::new(path)?;
log::trace!("Registered profile '{}' (system): {:?}", &profile, &res);
resources.insert(profile, res);
}
}
Ok(resources)
}
pub fn build_template_path(&self, path: PathBuf) -> Result<PathBuf> {
let p = self.templates.join(path);
if !p.is_file() {
return Err(WefterErr::TemplateNotFound(p).into());
}
Ok(p)
}
}