systemprompt_models/config/
mod.rs1use 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}