codetopo_server/
config.rs1use std::net::SocketAddr;
8use std::path::PathBuf;
9
10use crate::error::ApiError;
11use crate::keys::KeyStore;
12
13pub const DEFAULT_BIND: &str = "127.0.0.1:8080";
16pub const DEFAULT_DATA_DIR: &str = "./data";
18pub const DEFAULT_KEYS_FILE: &str = "./api_keys";
20pub const DEFAULT_METERING_LOG: &str = "./metering.log";
22
23#[derive(Debug, Clone)]
25pub struct Config {
26 pub data_dir: PathBuf,
28 pub keys_file: PathBuf,
30 pub metering_log: PathBuf,
32 pub bind: SocketAddr,
34}
35
36impl Config {
37 pub fn from_env() -> Result<Self, ApiError> {
43 let data_dir = env_path("CODETOPO_DATA_DIR", DEFAULT_DATA_DIR);
44 let keys_file = env_path("CODETOPO_KEYS_FILE", DEFAULT_KEYS_FILE);
45 let metering_log = env_path("CODETOPO_METERING_LOG", DEFAULT_METERING_LOG);
46 let bind = env_string("CODETOPO_BIND", DEFAULT_BIND);
47 let bind: SocketAddr = bind.parse().map_err(|_| {
48 ApiError::Internal(format!(
49 "CODETOPO_BIND must be a 'host:port' socket address, got '{bind}'"
50 ))
51 })?;
52 Ok(Config {
53 data_dir,
54 keys_file,
55 metering_log,
56 bind,
57 })
58 }
59
60 pub fn index_db_path(&self, index_id: &str) -> PathBuf {
62 self.data_dir.join(format!("{index_id}.db"))
63 }
64
65 pub async fn prepare(&self) -> Result<KeyStore, ApiError> {
67 tokio::fs::create_dir_all(&self.data_dir)
68 .await
69 .map_err(|err| {
70 ApiError::Internal(format!(
71 "cannot create data dir {}: {err}",
72 self.data_dir.display()
73 ))
74 })?;
75 KeyStore::load(&self.keys_file)
76 }
77}
78
79impl Default for Config {
80 fn default() -> Self {
81 Config {
82 data_dir: PathBuf::from(DEFAULT_DATA_DIR),
83 keys_file: PathBuf::from(DEFAULT_KEYS_FILE),
84 metering_log: PathBuf::from(DEFAULT_METERING_LOG),
85 bind: DEFAULT_BIND.parse().expect("default bind address is valid"),
86 }
87 }
88}
89
90fn env_string(key: &str, default: &str) -> String {
91 match std::env::var(key) {
92 Ok(value) if !value.trim().is_empty() => value,
93 _ => default.to_string(),
94 }
95}
96
97fn env_path(key: &str, default: &str) -> PathBuf {
98 PathBuf::from(env_string(key, default))
99}