1use crate::{overrides::apply_overrides, ConfigMode, MescError, RpcConfig};
2use std::{env, fs};
3
4pub fn is_mesc_enabled() -> bool {
6 if let Ok("DISABLED") = std::env::var("MESC_MODE").as_deref() {
7 return false;
8 };
9 let env_vars = [
10 "MESC_MODE",
11 "MESC_PATH",
12 "MESC_ENV",
13 "MESC_NETWORK_NAMES",
14 "MESC_NETWORK_DEFAULTS",
15 "MESC_ENDPOINTS",
16 "MESC_DEFAULT_ENDPOINT",
17 "MESC_GLOBAL_METADATA",
18 "MESC_ENDPOINT_METADATA",
19 "MESC_PROFILES",
20 ];
21 for env_var in env_vars.iter() {
22 match std::env::var(env_var).as_deref() {
23 Ok(value) if !value.is_empty() => return true,
24 _ => {}
25 }
26 }
27 false
28}
29
30pub fn get_config_mode() -> Result<ConfigMode, MescError> {
32 let mode = env::var("MESC_MODE").unwrap_or_default();
33 if mode == "PATH" {
34 return Ok(ConfigMode::Path);
35 } else if mode == "ENV" {
36 return Ok(ConfigMode::Env);
37 } else if mode == "DISABLED" {
38 return Ok(ConfigMode::Disabled);
39 } else if !mode.is_empty() {
40 return Err(MescError::InvalidConfigMode);
41 }
42 if let Ok(path) = env::var("MESC_PATH") {
43 if !path.is_empty() {
44 return Ok(ConfigMode::Path);
45 }
46 }
47 if let Ok(env_config) = env::var("MESC_ENV") {
48 if !env_config.is_empty() {
49 return Ok(ConfigMode::Env);
50 }
51 }
52
53 Ok(ConfigMode::Disabled)
54}
55
56pub fn load_config_data() -> Result<RpcConfig, MescError> {
58 let config = match get_config_mode() {
59 Ok(ConfigMode::Path) => load_file_config(None),
60 Ok(ConfigMode::Env) => load_env_config(),
61 Ok(ConfigMode::Disabled) => Err(MescError::MescNotEnabled),
62 Err(e) => Err(e),
63 };
64
65 let mut config = config?;
66 apply_overrides(&mut config)?;
67 Ok(config)
68}
69
70pub fn load_env_config() -> Result<RpcConfig, MescError> {
72 let config_json = env::var("MESC_ENV")?;
73 serde_json::from_str(&config_json).map_err(|_| MescError::InvalidJson)
74}
75
76pub fn load_file_config(path: Option<String>) -> Result<RpcConfig, MescError> {
78 let path = match path {
79 Some(path) => path,
80 None => get_config_path()?,
81 };
82 if !std::path::Path::new(path.as_str()).exists() {
83 return Err(MescError::MissingConfigFile(path));
84 };
85 let config_str = fs::read_to_string(path).map_err(MescError::IOError)?;
86 serde_json::from_str(&config_str).map_err(|_| MescError::InvalidJson)
87}
88
89pub fn get_config_path() -> Result<String, MescError> {
91 let path = env::var("MESC_PATH")?;
92 let path = expand_path(path)?;
93 Ok(path)
94}
95
96pub fn expand_path<P: AsRef<std::path::Path>>(path: P) -> Result<String, MescError> {
98 let path_str =
99 path.as_ref().to_str().ok_or(MescError::InvalidPath("Invalid path".to_string()))?;
100
101 if let Some(subpath) = path_str.strip_prefix("~/") {
102 Ok(format!("{}/{}", env::var("HOME")?, subpath))
103 } else {
104 Ok(path_str.to_string())
105 }
106}