Skip to main content

systemprompt_models/config/
mod.rs

1//! `config` module — see crate-level docs for context.
2
3use std::sync::OnceLock;
4use systemprompt_traits::ConfigProvider;
5
6use crate::auth::JwtAudience;
7use crate::profile::{ContentNegotiationConfig, SecurityHeadersConfig};
8
9mod environment;
10mod paths;
11mod rate_limits;
12mod validation;
13mod verbosity;
14
15pub use environment::Environment;
16pub use paths::PathNotConfiguredError;
17pub use rate_limits::RateLimitConfig;
18pub use validation::{
19    format_path_errors, validate_optional_path, validate_postgres_url, validate_profile_paths,
20    validate_required_optional_path, validate_required_path,
21};
22pub use verbosity::VerbosityLevel;
23
24static CONFIG: OnceLock<Config> = OnceLock::new();
25
26#[derive(Debug, Clone)]
27pub struct Config {
28    pub sitename: String,
29    pub database_type: String,
30    pub database_url: String,
31    pub database_write_url: Option<String>,
32    pub github_link: String,
33    pub github_token: Option<String>,
34    pub system_path: String,
35    pub services_path: String,
36    pub bin_path: String,
37    pub skills_path: String,
38    pub settings_path: String,
39    pub content_config_path: String,
40    pub geoip_database_path: Option<String>,
41    pub web_path: String,
42    pub web_config_path: String,
43    pub web_metadata_path: String,
44    pub host: String,
45    pub port: u16,
46    pub api_server_url: String,
47    pub api_internal_url: String,
48    pub api_external_url: String,
49    pub jwt_issuer: String,
50    pub jwt_access_token_expiration: i64,
51    pub jwt_refresh_token_expiration: i64,
52    pub jwt_audiences: Vec<JwtAudience>,
53    pub use_https: bool,
54    pub rate_limits: RateLimitConfig,
55    pub cors_allowed_origins: Vec<String>,
56    pub is_cloud: bool,
57    pub content_negotiation: ContentNegotiationConfig,
58    pub security_headers: SecurityHeadersConfig,
59    pub allow_registration: bool,
60}
61
62impl Config {
63    pub fn is_initialized() -> bool {
64        CONFIG.get().is_some()
65    }
66
67    pub fn get() -> Result<&'static Self, crate::errors::ConfigError> {
68        CONFIG
69            .get()
70            .ok_or(crate::errors::ConfigError::NotInitialized)
71    }
72
73    pub fn install(config: Self) -> Result<(), Box<Self>> {
74        CONFIG.set(config).map_err(Box::new)
75    }
76}
77
78impl ConfigProvider for Config {
79    fn get(&self, key: &str) -> Option<String> {
80        match key {
81            "database_type" => Some(self.database_type.clone()),
82            "database_url" => Some(self.database_url.clone()),
83            "database_write_url" => self.database_write_url.clone(),
84            "host" => Some(self.host.clone()),
85            "port" => Some(self.port.to_string()),
86            "system_path" => Some(self.system_path.clone()),
87            "services_path" => Some(self.services_path.clone()),
88            "bin_path" => Some(self.bin_path.clone()),
89            "skills_path" => Some(self.skills_path.clone()),
90            "settings_path" => Some(self.settings_path.clone()),
91            "content_config_path" => Some(self.content_config_path.clone()),
92            "web_path" => Some(self.web_path.clone()),
93            "web_config_path" => Some(self.web_config_path.clone()),
94            "web_metadata_path" => Some(self.web_metadata_path.clone()),
95            "sitename" => Some(self.sitename.clone()),
96            "github_link" => Some(self.github_link.clone()),
97            "github_token" => self.github_token.clone(),
98            "api_server_url" => Some(self.api_server_url.clone()),
99            "api_external_url" => Some(self.api_external_url.clone()),
100            "jwt_issuer" => Some(self.jwt_issuer.clone()),
101            "is_cloud" => Some(self.is_cloud.to_string()),
102            _ => None,
103        }
104    }
105
106    fn database_url(&self) -> &str {
107        &self.database_url
108    }
109
110    fn database_write_url(&self) -> Option<&str> {
111        self.database_write_url.as_deref()
112    }
113
114    fn system_path(&self) -> &str {
115        &self.system_path
116    }
117
118    fn api_port(&self) -> u16 {
119        self.port
120    }
121
122    fn as_any(&self) -> &dyn std::any::Any {
123        self
124    }
125}