use std::{fs, path}; use std::io::ErrorKind; use toml; enum PathType { Exclude, DoNotScan, Okay, } pub struct Config { config: toml::Value, commands: toml::Value, } impl Config { pub fn new() -> Config { println!("Using built-in config"); Config { config: toml::toml!{ source = "src" build_dir = "build" do_not_scan = [] exclude = [] file_delim = ":?" command_delim = ":!" commands_file = "commands.toml" }, commands: toml::toml!{ empty = "" } } } pub fn import(config: &str) -> Config { println!("Using found config"); let config: toml::Value = toml::from_str(config).expect("Could not load config"); let config = config.get("config").expect("Could not find \"[config]\" field"); // Attempt to read commands file let commands: toml::Value = match config.get("commands_file") { Some(n) => { if n.is_str() { let file_string = n.as_str().unwrap(); let file_string = match fs::read_to_string(file_string) { Ok(n) => n, Err(_) => {println!("Could not load commands from file"); String::from("[commands]")}, }; toml::from_str(file_string.as_str()).expect("Invalid toml") } else { panic!() } }, None => {println!("Could not load commands from file"); toml::toml!{[commands]}}, }; let commands = commands.get("commands").expect("Could not find \"[commands]\" field"); Config { config: config.clone(), commands: commands.clone(), } } pub fn get_str(&self, string: &str) -> Option<&str> { match self.config.get(string) { Some(n) => n.as_str(), None => None } } pub fn get_cmd_str(&self, string: &str) -> Option<&str> { match self.commands.get(string) { Some(n) => n.as_str(), None => None } } } fn create_dir(path: &path::PathBuf) -> Result<(), ()> { match fs::create_dir(path) { Ok(_) => (), Err(n) => match n.kind() { ErrorKind::AlreadyExists => (), _ => return Err(()), } } return Ok(()) } fn remove_path_head(path: &path::PathBuf) -> path::PathBuf { let mut path = path.to_str().unwrap().split("/"); path.next(); let path: path::PathBuf = path.collect(); return path } fn append_path_head(path: &path::PathBuf, head: &str) -> path::PathBuf { let mut head = path::PathBuf::from(head); head.push(path); return head } fn replace_path_head(path: &path::PathBuf, head: &str) -> path::PathBuf { let path = remove_path_head(path); append_path_head(&path, head) } pub fn run(config: Config) { let source = config.get_str("source").unwrap(); let build = config.get_str("build_dir").unwrap(); // Create build directory or panic create_dir(&path::PathBuf::from(build)).unwrap(); directory_scan(path::PathBuf::from(source), &config); } fn check_path(path: &path::PathBuf, config: &Config) -> PathType { // GET EXCLUDE AND DNS LISTS // CHECK FOR EXCLUDES AND DO NOT SCANS // Excludes // for ex_path in excludes { // if &ex_path == &path { // return PathType::Exclude; // } // } // // Do not scans (copy files) // for dns_path in dns { // if &dns_path == &path { // return PathType::DoNotScan; // } // } PathType::Exclude } fn copy_file(path: &path::PathBuf) {} fn directory_scan(path: path::PathBuf, config: &Config) { println!("Scanning: {:?}", &path); // Check the path match check_path(&path, config) { PathType::Exclude => return, _ => (), }; // Create the dir in the build tree let build_path = replace_path_head(&path, "build/"); create_dir(&build_path).unwrap(); // Iterate over path contents for x in fs::read_dir(path).unwrap() { let x = x.as_ref().unwrap().path(); if x.is_dir() { directory_scan(x, &config); } else { file_scan(x, &config); } } } fn file_scan(path: path::PathBuf, config: &Config) { // Check path match check_path(&path, config) { PathType::Okay => (), PathType::DoNotScan => {copy_file(&path); return}, PathType::Exclude => return, }; // File scanning let mut file_string = String::new(); for line in fs::read_to_string(&path).unwrap().lines() { if line.contains(":?") { let v: Vec<&str> = line.trim().split(":?").collect(); let v = v.get(1).unwrap(); println!("INSERTING {} into {:?}", v, path); file_string.push_str(fs::read_to_string(v).unwrap().as_ref()); } else { file_string.push_str(line); file_string.push('\n') } } let dest = replace_path_head(&path, "build/"); fs::write(dest, file_string).expect("Could not write file"); }