在rust項目中使用yml配置文件


在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 }

yml_rust完整代碼可以在github上找到


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM