Skip to main content

rust_serv/config/
loader.rs

1use crate::config::Config;
2use crate::error::Result;
3use std::fs;
4use std::path::Path;
5
6/// Load configuration from a TOML file
7pub fn load_config<P: AsRef<Path>>(path: P) -> Result<Config> {
8    let content = fs::read_to_string(path)?;
9    let config: Config = toml::from_str(&content)
10        .map_err(|e| crate::error::Error::Config(format!("Failed to parse config: {}", e)))?;
11    Ok(config)
12}
13
14#[cfg(test)]
15mod tests {
16    use super::*;
17    use tempfile::NamedTempFile;
18    use std::io::Write;
19
20    #[test]
21    fn test_load_valid_config() {
22        let mut file = NamedTempFile::new().unwrap();
23        write!(file, r#"
24            port = 9000
25            root = "/test"
26        "#).unwrap();
27        let config = load_config(file.path()).unwrap();
28        assert_eq!(config.port, 9000);
29    }
30
31    #[test]
32    fn test_load_invalid_config() {
33        let mut file = NamedTempFile::new().unwrap();
34        writeln!(file, "invalid = [").unwrap();
35        assert!(load_config(file.path()).is_err());
36    }
37
38    #[test]
39    fn test_load_nonexistent_file() {
40        let result = load_config("/nonexistent/config.toml");
41        assert!(result.is_err());
42    }
43
44    #[test]
45    fn test_load_empty_config() {
46        let mut file = NamedTempFile::new().unwrap();
47        write!(file, "").unwrap();
48        let config = load_config(file.path()).unwrap();
49        // Should use default values
50        assert_eq!(config.port, 8080); // default port
51    }
52
53    #[test]
54    fn test_load_partial_config() {
55        let mut file = NamedTempFile::new().unwrap();
56        write!(file, r#"
57            port = 3000
58            enable_indexing = false
59        "#).unwrap();
60        let config = load_config(file.path()).unwrap();
61        assert_eq!(config.port, 3000);
62        assert_eq!(config.enable_indexing, false);
63    }
64
65    #[test]
66    fn test_load_config_with_invalid_toml() {
67        let mut file = NamedTempFile::new().unwrap();
68        write!(file, "this is not valid toml [[[").unwrap();
69        let result = load_config(file.path());
70        assert!(result.is_err());
71        let error_msg = result.unwrap_err().to_string();
72        assert!(error_msg.contains("Failed to parse config"));
73    }
74
75    #[test]
76    fn test_load_config_with_all_fields() {
77        let mut file = NamedTempFile::new().unwrap();
78        write!(file, r#"
79            port = 9000
80            root = "/var/www"
81            enable_indexing = true
82            enable_compression = true
83            log_level = "debug"
84            enable_tls = false
85            connection_timeout_secs = 60
86            max_connections = 500
87            enable_health_check = true
88        "#).unwrap();
89        let config = load_config(file.path()).unwrap();
90        assert_eq!(config.port, 9000);
91        assert_eq!(config.root, std::path::PathBuf::from("/var/www"));
92        assert_eq!(config.enable_indexing, true);
93        assert_eq!(config.enable_compression, true);
94        assert_eq!(config.log_level, "debug");
95    }
96}