use colored::Colorize;
use once_cell::sync::Lazy;
#[allow(dead_code)]
#[derive(serde_derive::Deserialize, serde_derive::Serialize, Debug, Clone)]
pub struct Environment {
pub current_dir: String,
pub crate_dirs: Vec<String>,
pub global_vars: Vec<toml::Value>,
pub return_val: String,
pub debug: bool,
}
#[allow(dead_code)]
impl Environment {
pub fn default() -> Self {
Self { current_dir: String::new(), crate_dirs: Vec::new(), global_vars: Vec::new(), return_val: String::new(), debug: false }
}
pub fn load() -> Environment {
toml::from_str(
&std::fs::read_to_string(ENV_PATH.as_path())
.unwrap_or(String::new()))
.unwrap_or(Environment::default())
}
pub fn load_into(&mut self) {
let temp = Environment::load();
self.current_dir = temp.current_dir;
self.global_vars = temp.global_vars;
self.return_val = temp.return_val;
self.debug = temp.debug;
}
pub fn save(&self) {
std::fs::write(ENV_PATH.as_path(), toml::to_string(self).unwrap_or(ENV_DEFAULT.into())).unwrap();
}
pub fn return_and_save(&mut self, value: &str) {
self.return_val = value.into();
Environment::save(self);
}
}
pub fn load() -> Environment {
Environment::load()
}
pub fn load_into(env: &mut Environment) {
Environment::load_into(env)
}
pub fn save(env: &Environment) {
Environment::save(env)
}
pub fn print_message(msg: &str) {
println!("{}", msg.bold().color(ORANGE))
}
pub const ORANGE: colored::Color = colored::Color::TrueColor {
r: 255,
g: 127,
b: 80,
};
pub static PROJECT_DIRS: Lazy<directories::ProjectDirs> = Lazy::new(||
match directories::ProjectDirs::from("com", "", "crab") {
None => {
println!("Unable to write to home directory, maybe you don't have permissions?");
std::process::exit(1);
}
Some(v) => {
v
}
});
pub static USER_DIRS: Lazy<directories::UserDirs> = Lazy::new(||
match directories::UserDirs::new(){
None => {
println!("Unable to access the home directory, maybe you don't have permissions?");
std::process::exit(1);
}
Some(v) => {
v
}
});
pub const CONFIG_PATH: Lazy<&'static std::path::Path> = Lazy::new(|| PROJECT_DIRS.config_dir());
pub const ENV_DEFAULT: &'static str = include_str!("env.toml");
pub static ENV_PATH: Lazy<std::path::PathBuf> = Lazy::new(|| CRATES_PATH.join("env.toml"));
pub static CRATES_PATH: Lazy<std::path::PathBuf> = Lazy::new(|| PROJECT_DIRS.config_dir().join("crates"));
pub static CRATES: Lazy<std::collections::HashSet<String>> = Lazy::new(|| {
let mut crates = std::collections::HashSet::new();
let dirs = match CRATES_PATH.read_dir() {
Ok(p) => p,
Err(_) => {
let config = CONFIG_PATH.to_str().unwrap();
println!("{}", "\nFirst time starting Crab (or the crab config folder was deleted).\n\nDownloading essential crates from https://github.com/LyonSyonII/Crab-Shell".bold().color(ORANGE));
let git = std::process::Command::new("git")
.args(["clone", "--depth", "1", "--filter=blob:none", "--no-checkout", "https://github.com/LyonSyonII/Crab-Shell", config]).status();
if let Err(e) = git {
println!("{} {}", "error: ".red(), e.to_string());
println!("{}: Check if you have 'Git' installed, and if you have write permissions.", "error".red());
std::process::exit(1);
}
std::env::set_current_dir(config).unwrap();
let git = std::process::Command::new("git").args(["checkout", "master", "--", "crates"]).status();
if let Err(e) = git {
println!("{}: {}", "error: ".red(), e.to_string());
std::process::exit(1);
}
println!("{}", "\nDownload completed, compiling Crates: ".bold().color(ORANGE));
for cr in include_str!("core_crates.txt").split_whitespace() {
println!("\n{}", cr.bold());
std::process::Command::new("cargo")
.arg("build")
.arg("--release")
.arg(format!(
"--manifest-path={}/{}/Cargo.toml",
CRATES_PATH.to_string_lossy(),
cr
))
.status()
.expect(&format!("Crate {} failed to build", cr));
}
CRATES_PATH.read_dir().unwrap()
}
};
for file in dirs {
if file.is_err() {
break;
}
if file.as_ref().unwrap().file_type().unwrap().is_dir() {
crates.insert(file.unwrap().file_name().to_string_lossy().into());
}
}
for dir in load().crate_dirs {
for file in std::fs::read_dir(dir).unwrap() {
if file.is_err() {
break;
}
let file = file.unwrap();
if file.file_type().unwrap().is_dir() {
crates.insert(file.file_name().to_string_lossy().into());
}
}
}
crates.insert("exit".into());
crates.insert("let ".into());
crates.insert(":".into());
crates.insert("=".into());
crates.insert("$".into());
crates
});