在rust項目中使用yml配置文件
引言
在接觸rust之前一直是使用java,已經習慣了springboot那一套東西,所以對使用.env或者.toml做配置文件都不習慣。就想着復刻springboot的配置習慣,花了點時間做好了,就不知道自己做的怎么樣,請諸位大佬指教。
第一步:創建項目
cargo new yml_rust
第二步:創建配置文件
cd yml_rust
mkdir resources #經過實踐我發現rust打包的時候不會包含配置文件,所以我建議配置文件和src文件夾平級這樣方便在發布時復制配置文件
cd resources
touch application.yml application-dev.yml application-test.yml application-prod.yml #創建配置配置文件
# application.yml 環境配置文件 可以通過配置dev、test、prod切換配置
# application-dev.yml 開發環境配置
# application-test.yml 測試環境配置
# application-prod.yml 生產環境配置
編輯 application.yml 添加一下內容:
#切換配置文件
profiles:
active: dev
編輯 application-dev.yml 添加一下內容:
# mysql 配置
mysql:
host: 127.0.0.1
port: 3306
user: root
password: jishuzhai
db: rust_book
#最小連接數
pool_min_idle: 8
#最大連接數
pool_max_open: 32
#連接超時時間單位秒
timeout_seconds: 15
編輯 application-prod.yml 添加一下內容:
# mysql 配置
mysql:
host: 127.0.0.2
port: 3306
user: root
password: jishuzhai
db: rust_book
#最小連接數
pool_min_idle: 8
#最大連接數
pool_max_open: 32
#連接超時時間單位秒
timeout_seconds: 15
編輯 application-test.yml 添加一下內容:
# mysql 配置
mysql:
host: 127.0.0.3
port: 3306
user: root
password: jishuzhai
db: rust_book
#最小連接數
pool_min_idle: 8
#最大連接數
pool_max_open: 32
#連接超時時間單位秒
timeout_seconds: 15
注意dev和prod、test的差異只有ip地址不一樣 這是為了后面測試切換功能
第三步:添加配置
在Cargo.toml文件中[dependencies]標簽下添加一下配置:
serde = { version = "1.0.125", features = ["derive"] }
serde_json = "1.0.75"
lazy_static = "1.4.0"
serde_yaml = "0.8.23"
schemars = "0.8.8"
第四步:編寫讀取配置代碼
cd /Users/fuping/Desktop/yml_rust/src
mkdir load_config #加載配置文件的代碼模塊
touch load_config/mod.rs load_config/models.rs load_config/init_load_config.rs
mkdir util #全局變量
touch util/mod.rs util/constant.rs
編輯 load_config/mod.rs文件添加一下代碼:
/****
* 加載系統配置
*/
pub mod models;
pub mod init_load_config;
編輯load_config/models.rs 添加一下代碼
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct GlobalConfig {
pub mysql: Mysql,
}
#[derive(Debug,Serialize, Deserialize)]
pub struct Mysql {
pub host: String,
pub port: u32,
pub user: String,
pub password: String,
pub db: String,
pub pool_min_idle: u64,
pub pool_max_open: u64,
pub timeout_seconds: u64,
}
#[derive(Serialize, Deserialize)]
pub struct Profiles {
pub active: String,
}
#[derive(Serialize, Deserialize)]
pub struct EnvConfig {
pub profiles: Profiles,
}
編輯load_config/init_load_config.rs文件添加一下代碼
use crate::load_config::models::{GlobalConfig, EnvConfig};
use schemars::schema::RootSchema;
use serde_yaml::from_str as yaml_from_str;
use serde_json::{from_str as json_from_str, to_string_pretty};
use std::fs::read_to_string;
///
/// 加載環境配置
///
///
fn load_env_conf() -> Option<EnvConfig> {
let schema = yaml_from_str::<RootSchema>(
&read_to_string("resources/application.yml").expect("Error loading configuration file resources/application.yml, please check the configuration!"),
);
return match schema {
Ok(json) => {
let data = to_string_pretty(&json).expect("resources/application.yml file data error!");
let p: EnvConfig = json_from_str(&*data).expect("Failed to transfer JSON data to EnvConfig object!");
return Some(p);
}
Err(err) => {
println!("{}", err);
None
}
};
}
///
/// 根據環境配置加載全局配置
/// action dev 開始環境 test 測試環境 prod 生產環境
///
fn load_global_config(action: String) -> Option<GlobalConfig> {
let path = format!("resources/application-{}.yml", &action);
let schema = yaml_from_str::<RootSchema>(
&read_to_string(&path).unwrap_or_else(|_| panic!("Error loading configuration file {}, please check the configuration!", &path)),
);
return match schema {
Ok(json) => {
let data = to_string_pretty(&json).unwrap_or_else(|_| panic!("{} file data error!, please check the configuration!", path));
let p = json_from_str(&*data).expect("Failed to transfer JSON data to BriefProConfig object!");
return Some(p);
}
Err(err) => {
println!("{}", err);
None
}
};
}
///
/// 先加載環境配置 在根據當前加載的環境 去加載相應的信息
///
pub fn load_conf() -> Option<GlobalConfig> {
println!("{}", "Load profile");
if let Some(init) = load_env_conf() {
return load_global_config(init.profiles.active);
}
None
}
#[test]
fn test_load_env_conf_mysql() {
let pro = load_conf();
pro.as_ref().map(|a| {
println!("mysqlConfig:{}", serde_json::to_string(&a.mysql).unwrap());
});
}
第五步:測試
運行test_load_env_conf_mysql 測試看看運行結果,正常情況下會打印一下結果:
Load profile
mysqlConfigs:{"host":"127.0.0.1","port":3306,"user":"root","password":"jishuzhai","db":"rust_book","pool_min_idle":8,"pool_max_open":32,"timeout_seconds":15}
然后編輯application.yml 更改配置查看配置切換是否正常。
在項目中使用:
編輯util/mod.rs 文件添加以下內容:
pub mod constant;
編輯util/constant.rs文件添加以下內容:
use lazy_static::lazy_static;
use crate::load_config::models::GlobalConfig;
use crate::load_config::init_load_config::load_conf;
lazy_static! {
///
/// 全局配置
///
pub static ref GLOBAL_CONFIG: GlobalConfig = load_conf().unwrap();
}
編輯main.rs 添加以下內容
mod load_config;
mod util;
use util::constant::GLOBAL_CONFIG;
fn main() {
let config = &GLOBAL_CONFIG;
println!("{:?}", config.mysql);
}
運行項目
cargo run
運行結果如下:
Load profile
Mysql { host: "127.0.0.3", port: 3306, user: "root", password: "jishuzhai", db: "rust_book", pool_min_idle: 8, pool_max_open: 32, timeout_seconds: 15 }