1use std::{collections::HashMap, path::Path};
41
42use crate::Run::{
43 Constant::ProfileDefault,
44 Definition::{Profile, RunProfileConfig},
45 Error::{Error, Result},
46};
47
48pub fn load_profiles(config_path:&Path) -> Result<HashMap<String, Profile>> {
58 let content =
59 std::fs::read_to_string(config_path).map_err(|_e| Error::ConfigNotFound(config_path.to_path_buf()))?;
60
61 let config:serde_json::Value = serde_json::from_str(&content).map_err(|e| Error::ConfigParse(e.to_string()))?;
62
63 let mut profiles = HashMap::new();
64
65 if let Some(profiles_obj) = config.get("profiles").and_then(|v| v.as_object()) {
66 for (name, value) in profiles_obj {
67 if let Ok(profile) = serde_json::from_value::<Profile>(value.clone()) {
68 profiles.insert(name.clone(), profile);
69 }
70 }
71 }
72
73 Ok(profiles)
74}
75
76pub fn resolve_name(name:&str, aliases:&HashMap<String, String>) -> String {
87 aliases.get(name).cloned().unwrap_or_else(|| name.to_string())
88}
89
90pub fn default_name() -> String { ProfileDefault.to_string() }
96
97pub fn validate(profile:&Profile) -> (Vec<String>, Vec<String>) {
107 let mut warnings = Vec::new();
108
109 let mut issues = Vec::new();
110
111 if profile.description.is_none() {
113 warnings.push("Profile has no description".to_string());
114 }
115
116 if profile.workbench.is_none() {
118 issues.push("Profile has no workbench type specified".to_string());
119 }
120
121 if profile.env.is_none() || profile.env.as_ref().unwrap().is_empty() {
123 warnings.push("Profile has no environment variables defined".to_string());
124 }
125
126 if let Some(run_config) = &profile.run_config {
128 if run_config.live_reload_port == 0 {
129 issues.push("Live-reload port cannot be 0".to_string());
130 }
131 }
132
133 (warnings, issues)
134}
135
136pub fn merge(base:&Profile, override_profile:&Profile) -> Profile {
147 Profile {
148 name:base.name.clone(),
149
150 description:override_profile.description.clone().or_else(|| base.description.clone()),
151
152 workbench:override_profile.workbench.clone().or_else(|| base.workbench.clone()),
153
154 env:{
155 let mut env = base.env.clone().unwrap_or_default();
156
157 if let Some(override_env) = &override_profile.env {
158 for (key, value) in override_env {
159 env.insert(key.clone(), value.clone());
160 }
161 }
162
163 if env.is_empty() { None } else { Some(env) }
164 },
165
166 run_config:override_profile.run_config.clone().or_else(|| base.run_config.clone()),
167 }
168}
169
170pub fn from_env(name:&str, env_vars:HashMap<String, String>) -> Profile {
181 Profile {
182 name:name.to_string(),
183
184 description:Some("Environment-based profile".to_string()),
185
186 workbench:env_vars.get("Workbench").cloned(),
187
188 env:Some(env_vars),
189
190 run_config:None,
191 }
192}
193
194pub fn get_run_config(profile:&Profile) -> RunProfileConfig {
204 profile
205 .run_config
206 .clone()
207 .unwrap_or_else(|| RunProfileConfig { hot_reload:true, watch:true, live_reload_port:3001, features:None })
208}