1use std::{collections::HashMap, fs, str::FromStr};
2
3use serde::Deserialize;
4
5#[derive(Debug, Deserialize)]
6pub struct Config {
7 pub root_folder: String,
9 pub log_file: String,
11 pub index_file: String,
13 pub not_found_file: String,
15 pub mime_types: HashMap<String, String>,
17}
18
19impl Default for Config {
20 fn default() -> Self {
21 Self {
22 root_folder: "public".to_string(),
23 log_file: "logs.log".to_string(),
24 index_file: "index.html".to_string(),
25 not_found_file: "404.html".to_string(),
26 mime_types: [("html".into(), "text/html".into())].into_iter().collect()
27 }
28 }
29}
30
31impl FromStr for Config {
32 type Err = String;
33
34 fn from_str(s: &str) -> Result<Self, String> {
36 toml::from_str(s).map_err(|e| format!("Failed to parse TOML: {e}"))
37 }
38}
39
40impl Config {
41 pub fn from_file(path: &str) -> Result<Self, String> {
43 let content = fs::read_to_string(path).map_err(|e| format!("Failed to read config: {e}"))?;
44 content.parse::<Config>()
45 }
46
47 pub fn mime_type(&self, extension: &str) -> &str {
49 self.mime_types
50 .get(extension)
51 .map(|s| s.as_str())
52 .unwrap_or("text/plain")
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn test_load_config() {
62 let toml = r#"
63 root_folder = "./public"
64 index_file = "index.html"
65 not_found_file = "404.html"
66 log_file = "logs.log"
67
68 [mime_types]
69 html = "text/html"
70 "#;
71
72 let config = Config::from_str(toml).unwrap();
73 assert_eq!(config.root_folder, "./public");
74 assert_eq!(config.index_file, "index.html");
75 assert_eq!(config.not_found_file, "404.html");
76 assert_eq!(config.log_file, "logs.log");
77 assert_eq!(config.mime_type("html"), "text/html");
78 assert_eq!(config.mime_type("txt"), "text/plain");
79 }
80
81 #[test]
82 fn test_default_config() {
83 let config = Config::default();
84 assert_eq!(config.root_folder, "public");
85 assert_eq!(config.index_file, "index.html");
86 assert_eq!(config.not_found_file, "404.html");
87 assert_eq!(config.log_file, "logs.log");
88 assert_eq!(config.mime_type("html"), "text/html");
89 }
90}