1use std::collections::HashMap;
7use std::path::{Path, PathBuf};
8use serde::{Deserialize, Serialize};
9use crate::error::MpsError;
10
11fn default_git_remote() -> String { "origin".into() }
12fn default_git_branch() -> String { "master".into() }
13fn default_command() -> String { "open".into() }
14fn default_aliases() -> HashMap<String, String> { HashMap::new() }
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct Config {
20 pub mps_dir: PathBuf,
21 pub storage_dir: PathBuf,
22 pub log_file: PathBuf,
23 #[serde(default = "default_git_remote")]
24 pub git_remote: String,
25 #[serde(default = "default_git_branch")]
26 pub git_branch: String,
27 #[serde(default = "default_command")]
29 pub default_command: String,
30 #[serde(default = "default_aliases")]
32 pub aliases: HashMap<String, String>,
33}
34
35impl Config {
36 pub fn default_config() -> Result<Self, MpsError> {
38 let home = dirs::home_dir()
39 .ok_or_else(|| MpsError::ConfigInvalid("cannot determine home directory".into()))?;
40 let mps_dir = home.join(".mps");
41 Ok(Config {
42 storage_dir: mps_dir.join("mps"),
43 log_file: mps_dir.join("mps.log"),
44 mps_dir,
45 git_remote: "origin".into(),
46 git_branch: "master".into(),
47 default_command: "open".into(),
48 aliases: HashMap::new(),
49 })
50 }
51
52 pub fn load(path: &Path) -> Result<Self, MpsError> {
55 if !path.exists() {
56 return Err(MpsError::ConfigNotFound(path.to_path_buf()));
57 }
58 let content = std::fs::read_to_string(path)?;
59
60 let normalised = content
62 .lines()
63 .map(|line| {
64 if let Some(rest) = line.strip_prefix(':') {
65 rest.to_string()
66 } else {
67 line.to_string()
68 }
69 })
70 .collect::<Vec<_>>()
71 .join("\n");
72
73 let cfg: Config = serde_yaml::from_str(&normalised)
74 .map_err(|e| MpsError::ConfigInvalid(e.to_string()))?;
75 Ok(cfg)
76 }
77
78 pub fn init(path: &Path) -> Result<(), MpsError> {
80 if path.exists() {
81 return Ok(());
82 }
83 let cfg = Self::default_config()?;
84 let yaml = serde_yaml::to_string(&cfg)?;
85 std::fs::write(path, yaml)?;
86 Ok(())
87 }
88
89 pub fn ensure_dirs(&self) -> Result<(), MpsError> {
91 std::fs::create_dir_all(&self.mps_dir)?;
92 std::fs::create_dir_all(&self.storage_dir)?;
93 if !self.log_file.exists() {
94 std::fs::write(&self.log_file, "")?;
95 }
96 Ok(())
97 }
98}
99
100pub fn default_config_path() -> PathBuf {
102 std::env::var("MPS_CONFIG")
103 .map(PathBuf::from)
104 .unwrap_or_else(|_| {
105 dirs::home_dir()
106 .unwrap_or_else(|| PathBuf::from("."))
107 .join(".mps_config.yaml")
108 })
109}