soma_gateway/config/
defaults.rs1use std::path::{Path, PathBuf};
2
3use super::ConfigError;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct GatewayPaths {
7 home: PathBuf,
8}
9
10impl GatewayPaths {
11 pub fn new(home: PathBuf) -> Result<Self, ConfigError> {
12 validate_gateway_home(&home)?;
13 Ok(Self { home })
14 }
15
16 pub fn from_env() -> Result<Self, ConfigError> {
17 let home = std::env::var_os("MCP_GATEWAY_HOME")
18 .map(|path| normalize_env_gateway_home(PathBuf::from(path)))
19 .unwrap_or_else(default_gateway_home);
20 Self::new(home)
21 }
22
23 #[must_use]
24 pub fn home(&self) -> &Path {
25 &self.home
26 }
27
28 #[must_use]
29 pub fn config_path(&self) -> PathBuf {
30 self.home.join("config.toml")
31 }
32
33 #[must_use]
34 pub fn env_path(&self) -> PathBuf {
35 self.home.join(".env")
36 }
37}
38
39const GATEWAY_HOME_DIRNAME: &str = ".mcp-gateway";
40
41fn default_gateway_home() -> PathBuf {
42 std::env::var_os("HOME")
43 .map(PathBuf::from)
44 .unwrap_or_else(|| PathBuf::from("."))
45 .join(GATEWAY_HOME_DIRNAME)
46}
47
48fn normalize_env_gateway_home(path: PathBuf) -> PathBuf {
49 if path.file_name().and_then(|name| name.to_str()) == Some(GATEWAY_HOME_DIRNAME) {
50 path
51 } else {
52 path.join(GATEWAY_HOME_DIRNAME)
53 }
54}
55
56fn validate_gateway_home(path: &Path) -> Result<(), ConfigError> {
57 if path.as_os_str().is_empty() {
58 return Err(ConfigError::invalid("gateway_home", "must not be empty"));
59 }
60 if !path.is_absolute() {
61 return Err(ConfigError::invalid("gateway_home", "must be absolute"));
62 }
63 let leaf = path
64 .file_name()
65 .and_then(|name| name.to_str())
66 .unwrap_or("");
67 if leaf != GATEWAY_HOME_DIRNAME {
68 return Err(ConfigError::invalid(
69 "gateway_home",
70 "must point at a .mcp-gateway directory",
71 ));
72 }
73 Ok(())
74}
75
76#[cfg(test)]
77#[path = "defaults_tests.rs"]
78mod tests;