use std::path::PathBuf;
use colored::Colorize;
use dirs::home_dir;
use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
pub enum ModuleState {
NotInstalled,
UpToDate,
NeedsUpdate(UpdateReason),
}
#[derive(Debug, Clone, Copy)]
pub enum UpdateReason {
TomlChanged,
TemplateChanged,
NewVersion,
}
#[derive(Deserialize, Serialize, Debug, PartialEq, Clone)]
pub struct PluginInfo {
pub plugin_info: Package,
pub placeholders: Option<IndexMap<String, EntryType>>,
pub supporting_files: Option<IndexMap<String, FileSystemEntry>>,
}
#[derive(Deserialize, Serialize, Debug, PartialEq, Clone)]
#[serde(untagged)]
pub enum FileSystemEntry {
Directory {
version: String,
path: String,
destination: Option<String>,
files: IndexMap<String, FileSystemEntry>,
},
File {
version: String,
path: String,
destination: Option<String>,
},
}
#[derive(Deserialize, Serialize, Debug, PartialEq, Clone)]
pub struct Package {
pub author: String,
pub version: String,
pub help: Option<String>,
pub internal_dependencies: Option<Vec<String>>,
pub external_dependencies: Option<Vec<String>>,
pub plugin_type: PluginType,
}
#[derive(Deserialize, Serialize, Debug, PartialEq, Clone)]
#[serde(untagged)]
pub enum PluginType {
Shell(String),
Script(String),
RustPackage {
path: Option<String>,
git: Option<String>,
tag: Option<String>,
},
}
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
#[serde(untagged)]
pub enum EntryType {
Value(String),
Object(IndexMap<String, EntryType>),
Array(Vec<EntryType>),
}
impl std::fmt::Display for EntryType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let EntryType::Value(val) = self {
return f.write_str(val);
}
f.write_str("")
}
}
#[derive(Deserialize, Serialize, Debug, PartialEq)]
pub struct GlobalConfig {
pub config_path: PathBuf,
pub git_repo: String,
#[serde(default = "default_branch")]
pub git_main_branch: String,
pub ssh_key: Option<String>,
#[serde(default)]
pub key_needs_pw: bool,
#[serde(default = "default_home")]
pub home: PathBuf,
}
fn default_branch() -> String {
"main".to_string()
}
fn default_home() -> PathBuf {
home_dir().expect("Could not find HOME").join(CONFIG_DIR)
}
pub static CONFIG_DIR: &str = ".terminal-magic";
impl GlobalConfig {
pub fn new() -> Self {
let config_dir = home_dir().expect("Could not find HOME").join(CONFIG_DIR);
let config_file = config_dir.join("global_config.toml");
let res: GlobalConfig;
if config_file.exists() {
res = toml::from_str(
&std::fs::read_to_string(&config_file).expect("Could not find global config"),
)
.expect("cannot parse config");
} else {
if !config_file.exists() {
std::fs::create_dir_all(&config_dir).expect("Could not create config dir");
}
res = Self {
config_path: config_file,
git_repo: String::from(""),
ssh_key: None,
key_needs_pw: false,
home: config_dir,
git_main_branch: String::from("main")
};
if res.save().is_err() {
eprintln!("{}", "Could not write config".red());
}
}
res
}
pub fn save(&self) -> std::io::Result<()> {
std::fs::write(self.config_path.as_path(), toml::to_string(self).unwrap())?;
Ok(())
}
}
impl Default for GlobalConfig {
fn default() -> Self {
Self::new()
}
}