diff --git a/Cargo.lock b/Cargo.lock index ab3264a..f2312c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2356,7 +2356,6 @@ dependencies = [ "sha2", "sqlx", "tokio", - "toml", "tracing", "tracing-appender", "tracing-subscriber", @@ -2645,15 +2644,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -3256,47 +3246,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", - "winnow", -] - -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - [[package]] name = "tower" version = "0.5.2" @@ -4028,15 +3977,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "winnow" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" -dependencies = [ - "memchr", -] - [[package]] name = "wit-bindgen" version = "0.45.0" diff --git a/Cargo.toml b/Cargo.toml index 60a56e7..26b7108 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,6 @@ serde_json = "1.0.143" sqlx = { version = "0.8.6", features = ["runtime-tokio-rustls", "postgres", "chrono", "uuid"] } uuid = { version = "1", features = ["v4"] } tokio = { version = "1", features = ["full"] } -toml = "0.8" base64 = "0.22" rsa = { version = "0.9", features = ["pem", "sha2"] } pkcs8 = "0.10" diff --git a/deploy/rust-backend-development.service b/deploy/rust-backend-development.service index 62d8af4..a03af11 100644 --- a/deploy/rust-backend-development.service +++ b/deploy/rust-backend-development.service @@ -22,7 +22,7 @@ Environment=SSL_KEY_PATH=/etc/ssl/private/private.key Environment=SSL_CERT_PATH=/etc/ssl/certs/full_chain.pem Environment=RUST_LOG=info,rust_backend=debug Environment=APP_VERSION=0.2.0 -Environment=FREE_USER_DATA_LIMIT=20 +Environment=FREE_USER_DATA_LIMIT=100 Environment=SENTRY_DSN=http://f02c7cce1dc746e2ad41b11397dab0db@127.0.0.1:9000/1 Environment=APP_BASE_URL=https://dev.xmclassmate.top Environment=ALIPAY_APP_ID=2021006148681106 diff --git a/src/config.rs b/src/config.rs index de5a697..7747b27 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,11 +1,9 @@ //! 应用配置模块 //! -//! 支持多环境配置加载,优先级:环境变量 > 环境配置 > 默认配置 +//! 从环境变量加载配置,不再使用 TOML 文件。 +//! systemd service 的 Environment= 是唯一的配置来源。 -use serde::Deserialize; -use std::path::PathBuf; - -#[derive(Debug, Deserialize, Clone)] +#[derive(Debug, Clone)] pub struct AppConfig { pub database_url: String, pub wechat_appid: String, @@ -20,65 +18,27 @@ pub struct AppConfig { impl AppConfig { pub fn load() -> Result { - let env = std::env::var("APP_ENV").unwrap_or_else(|_| "development".into()); + let environment = std::env::var("APP_ENV").unwrap_or_else(|_| "development".into()); - let manifest_dir = std::env::var("CARGO_MANIFEST_DIR") - .map(PathBuf::from) - .unwrap_or_else(|_| std::env::current_dir().unwrap()); + let app_config = Self { + database_url: env_or_fail("DATABASE_URL")?, + wechat_appid: env_or_fail("WECHAT_APPID")?, + wechat_secret: env_or_fail("WECHAT_SECRET")?, + jwt_secret: env_or_fail("JWT_SECRET")?, + ssl_key_path: std::env::var("SSL_KEY_PATH").unwrap_or_default(), + ssl_cert_path: std::env::var("SSL_CERT_PATH").unwrap_or_default(), + rust_log: std::env::var("RUST_LOG").unwrap_or_else(|_| "info".into()), + free_user_data_limit: std::env::var("FREE_USER_DATA_LIMIT") + .ok() + .and_then(|v| v.parse().ok()) + .unwrap_or(20), + environment, + }; - let config_dir = manifest_dir.join("config"); - - let default_path = config_dir.join("default.toml"); - let env_path = config_dir.join(format!("{}.toml", env)); - - let mut settings = toml::Table::new(); - - // 1. 加载 default.toml - if default_path.exists() { - let content = std::fs::read_to_string(&default_path) - .map_err(|e| format!("读取 default.toml 失败: {}", e))?; - let parsed: toml::Table = - toml::from_str(&content).map_err(|e| format!("解析 default.toml 失败: {}", e))?; - settings.extend(parsed); - } else { - return Err(format!("配置文件不存在: {}", default_path.display())); - } - - // 2. 合并环境配置(覆盖默认值) - if env_path.exists() { - let content = std::fs::read_to_string(&env_path) - .map_err(|e| format!("读取 {}.toml 失败: {}", env, e))?; - let parsed: toml::Table = - toml::from_str(&content).map_err(|e| format!("解析 {}.toml 失败: {}", env, e))?; - settings.extend(parsed); - } - - // 3. 从环境变量加载(最高优先级) - // 支持两种前缀:APP_*(推荐)和直接变量名(兼容 systemd EnvironmentFile) - if let Ok(val) = std::env::var("APP_DATABASE_URL") { - settings.insert("database_url".into(), toml::Value::String(val)); - } - if let Ok(val) = std::env::var("APP_JWT_SECRET").or_else(|_| std::env::var("JWT_SECRET")) { - settings.insert("jwt_secret".into(), toml::Value::String(val)); - } - if let Ok(val) = std::env::var("APP_WECHAT_APPID").or_else(|_| std::env::var("WECHAT_APPID")) { - settings.insert("wechat_appid".into(), toml::Value::String(val)); - } - if let Ok(val) = std::env::var("APP_WECHAT_SECRET").or_else(|_| std::env::var("WECHAT_SECRET")) { - settings.insert("wechat_secret".into(), toml::Value::String(val)); - } - if let Ok(val) = std::env::var("APP_RUST_LOG") { - settings.insert("rust_log".into(), toml::Value::String(val)); - } - if let Ok(val) = std::env::var("APP_FREE_USER_DATA_LIMIT") - && let Ok(num) = val.parse::() { - settings.insert("free_user_data_limit".into(), toml::Value::Integer(num)); - } - - let app_config: AppConfig = toml::from_str(&settings.to_string()) - .map_err(|e| format!("配置反序列化失败: {}", e))?; - - tracing::info!("配置加载成功,环境={}", app_config.environment); + tracing::info!( + "配置加载成功,环境={}", + app_config.environment + ); Ok(app_config) } @@ -95,3 +55,7 @@ impl AppConfig { self.environment == "production" } } + +fn env_or_fail(key: &str) -> Result { + std::env::var(key).map_err(|_| format!("环境变量 {} 未设置", key)) +}