use std::path::Path;
use std::path::PathBuf;
use std::fs;
use std::process;
#[derive(Debug)]
pub struct Module {
pub name: String,
pub path: PathBuf,
pub children: Vec<Self>,
}
impl Module<> {
#[allow(invalid_value)]
pub fn new(mist_path: PathBuf) -> Self {
let mut this: Self = unsafe { std::mem::MaybeUninit::<Self>::zeroed().assume_init() };
this.constructor(mist_path);
this
}
pub fn constructor(self: &mut Self, mist_path: PathBuf) -> () {
self.children=Vec::new();
self.name=mist_path.file_stem().and_then(|s| s.to_str()).expect("Failed to get module name").to_string();
self.path=mist_path;
if self.path.is_dir() {
let dir: PathBuf = self.path.clone();
let pkg_gate: PathBuf = self.path.join("package.mist");
if pkg_gate.exists() {
self.path=pkg_gate;
}
self.scan_directory(&dir);
}
}
fn scan_directory(self: &mut Self, search_dir: &Path) -> () {
let entries = match fs::read_dir(search_dir) {
Ok (entries,) => {entries}
Err (e,) => {
eprintln!("error: failed to read directory {}\n {}", search_dir.display(), e);
process::exit(1);
}
};
for entry in entries{
let entry = match entry {
Ok (entry,) => {entry}
Err (e,) => {
eprintln!("error: failed to read directory entry\n {}", e);
process::exit(1);
}
};
let child_path: PathBuf = entry.path();
if child_path==self.path {
continue
;
}
self.children.push(Module::new(child_path));
}
}
pub fn output_dir(self: &Self, parent_dir: &PathBuf) -> PathBuf {
if self.path.is_dir()||Some("package.mist")==self.path.file_name().unwrap().to_str() {
parent_dir.join(&self.name)
} else {
parent_dir.clone()
}
}
pub fn output_path(self: &Self, parent_dir: &PathBuf) -> PathBuf {
if self.path.is_dir()||Some("package.mist")==self.path.file_name().unwrap().to_str() {
parent_dir.join(&self.name).join("mod.rs")
} else {
parent_dir.join(&self.name).with_extension("rs")
}
}}
pub fn master_package(mist_path: PathBuf) -> Module {
let mut root_mod = Module::new(mist_path.clone());
let parent_dir: &Path = mist_path.parent().expect("Failed to get parent directory of root file");
root_mod.scan_directory(parent_dir);
root_mod
}