rusty_files/server/
config.rs1use serde::{Deserialize, Serialize};
2use std::path::PathBuf;
3
4#[derive(Debug, Clone, Deserialize, Serialize)]
5pub struct ServerConfig {
6 pub server: ServerSettings,
7 pub database: DatabaseSettings,
8 pub security: SecuritySettings,
9 pub performance: PerformanceSettings,
10 pub logging: LoggingSettings,
11}
12
13#[derive(Debug, Clone, Deserialize, Serialize)]
14pub struct ServerSettings {
15 pub host: String,
16 pub port: u16,
17 pub workers: usize,
18 pub keep_alive: u64,
19 pub client_timeout: u64,
20 pub enable_cors: bool,
21 pub cors_origins: Vec<String>,
22}
23
24#[derive(Debug, Clone, Deserialize, Serialize)]
25pub struct DatabaseSettings {
26 pub path: PathBuf,
27 pub pool_size: u32,
28 pub max_connections: u32,
29 pub connection_timeout: u64,
30}
31
32#[derive(Debug, Clone, Deserialize, Serialize)]
33pub struct SecuritySettings {
34 pub enable_auth: bool,
35 pub jwt_secret: String,
36 pub jwt_expiry: u64,
37 pub api_key: Option<String>,
38 pub rate_limit_per_minute: u32,
39}
40
41#[derive(Debug, Clone, Deserialize, Serialize)]
42pub struct PerformanceSettings {
43 pub max_search_results: usize,
44 pub search_timeout_ms: u64,
45 pub index_batch_size: usize,
46 pub cache_size: usize,
47 pub enable_compression: bool,
48}
49
50#[derive(Debug, Clone, Deserialize, Serialize)]
51pub struct LoggingSettings {
52 pub level: String,
53 pub format: String, pub file: Option<PathBuf>,
55}
56
57impl Default for ServerConfig {
58 fn default() -> Self {
59 Self {
60 server: ServerSettings {
61 host: "127.0.0.1".to_string(),
62 port: 8080,
63 workers: num_cpus::get(),
64 keep_alive: 75,
65 client_timeout: 30,
66 enable_cors: true,
67 cors_origins: vec!["http://localhost:*".to_string()],
68 },
69 database: DatabaseSettings {
70 path: PathBuf::from("./filesearch.db"),
71 pool_size: 10,
72 max_connections: 100,
73 connection_timeout: 30,
74 },
75 security: SecuritySettings {
76 enable_auth: false,
77 jwt_secret: uuid::Uuid::new_v4().to_string(),
78 jwt_expiry: 3600,
79 api_key: None,
80 rate_limit_per_minute: 100,
81 },
82 performance: PerformanceSettings {
83 max_search_results: 1000,
84 search_timeout_ms: 5000,
85 index_batch_size: 1000,
86 cache_size: 10000,
87 enable_compression: true,
88 },
89 logging: LoggingSettings {
90 level: "info".to_string(),
91 format: "pretty".to_string(),
92 file: None,
93 },
94 }
95 }
96}
97
98impl ServerConfig {
99 pub fn from_file(path: &PathBuf) -> anyhow::Result<Self> {
100 let settings = config::Config::builder()
101 .add_source(config::File::from(path.as_ref()))
102 .add_source(config::Environment::with_prefix("FILESEARCH"))
103 .build()?;
104
105 Ok(settings.try_deserialize()?)
106 }
107
108 pub fn load() -> anyhow::Result<Self> {
109 let config_paths = vec![
111 PathBuf::from("config/default.toml"),
112 PathBuf::from("config.toml"),
113 PathBuf::from("./default.toml"),
114 ];
115
116 for path in config_paths {
117 if path.exists() {
118 return Self::from_file(&path);
119 }
120 }
121
122 Ok(Self::default())
124 }
125}