mesc/
load.rs

1use crate::{overrides::apply_overrides, ConfigMode, MescError, RpcConfig};
2use std::{env, fs};
3
4/// check whether mesc is enabled
5pub 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
30/// get config mode
31pub 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
56/// load config data
57pub 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
70/// load env config
71pub 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
76/// load file config
77pub 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
89/// get config path
90pub 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
96/// expand tilde's in path
97pub 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}