fraiseql_server/config/
loader.rs1use std::{env, path::Path};
2
3use fraiseql_error::ConfigError;
4
5use crate::config::{RuntimeConfig, validation::ConfigValidator};
6
7impl RuntimeConfig {
8 pub fn from_file(path: impl AsRef<Path>) -> Result<Self, ConfigError> {
10 let path = path.as_ref();
11
12 let content = std::fs::read_to_string(path).map_err(|e| ConfigError::ReadError {
13 path: path.to_path_buf(),
14 source: e,
15 })?;
16
17 let config: RuntimeConfig =
18 toml::from_str(&content).map_err(|e| ConfigError::ParseError { source: e })?;
19
20 let validation = ConfigValidator::new(&config).validate();
22 let warnings = validation.into_result()?;
23
24 for warning in warnings {
26 tracing::warn!("Configuration warning: {}", warning);
27 }
28
29 Ok(config)
30 }
31
32 pub fn load() -> Result<Self, ConfigError> {
34 if let Ok(path) = env::var("FRAISEQL_CONFIG") {
36 return Self::from_file(&path);
37 }
38
39 let local_config = Path::new("./fraiseql.toml");
41 if local_config.exists() {
42 return Self::from_file(local_config);
43 }
44
45 if let Some(config_dir) = dirs::config_dir() {
47 let user_config = config_dir.join("fraiseql/config.toml");
48 if user_config.exists() {
49 return Self::from_file(&user_config);
50 }
51 }
52
53 Err(ConfigError::NotFound)
54 }
55
56 pub fn load_with_path(path: Option<&Path>) -> Result<Self, ConfigError> {
58 match path {
59 Some(p) => Self::from_file(p),
60 None => Self::load(),
61 }
62 }
63
64 pub fn validate_syntax(content: &str) -> Result<(), ConfigError> {
66 let _config: RuntimeConfig =
67 toml::from_str(content).map_err(|e| ConfigError::ParseError { source: e })?;
68 Ok(())
69 }
70}