use std::collections::HashMap; use std::fs; use std::io::Write; use serde::{Deserialize, Serialize}; /// Config 结构体包含一个 HashMap,其中键是 String 类型,值是 WebSycnConf 类型。 #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] pub(crate) struct Config { pub inner: HashMap, } #[allow(dead_code)] impl Config { /// 创建一个新的 Config 实例。 /// /// # 返回值 /// 返回一个包含空 HashMap 的 Config 实例。 pub fn new() -> Self { Self { inner: HashMap::new(), } } /// 从指定路径加载配置文件。 /// /// 该方法尝试从给定路径读取文件,并解析 TOML 格式的数据。 /// /// # 参数 /// - `path`: 配置文件的路径。 /// /// # 返回值 /// 返回一个 `Result`,成功时包含 `Config` 实例,失败时包含错误信息。 pub fn load(path: &str) -> crate::Result { // 读取文件内容 let data = std::fs::read_to_string(path)?; // 解析 TOML 数据 match toml::from_str::(&data) { Ok(config) => Ok(config), Err(e) => Err(Box::new(e)), } } /// 将当前配置保存到指定路径。 /// /// 该方法将当前配置序列化为 TOML 格式,并写入到指定路径的文件中。 /// /// # 参数 /// - `path`: 配置文件的保存路径。 /// /// # 返回值 /// 返回一个 `Result`,成功时返回 `Ok(())`,失败时返回错误信息。 pub fn save(&self, path: &str) -> crate::Result<()> { // 将配置序列化为 TOML 格式的字符串 let data = toml::to_string_pretty(&self)?; // 打开文件并写入数据 let mut config = fs::OpenOptions::new() .read(true) .write(true) .create(true) .open(path)?; config.write_all(data.as_bytes())?; config.flush()?; Ok(()) } } /// WebSycnConf 结构体表示一个同步配置,包括源路径和目标路径。 #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] pub(crate) struct WebSycnConf { /// 源路径 from: String, /// 目标路径 dest: String, } #[allow(dead_code)] impl WebSycnConf { /// 创建一个新的 WebSycnConf 实例。 /// /// # 参数 /// - `from`: 源路径 /// - `dest`: 目标路径 /// /// # 返回值 /// 返回一个新的 WebSycnConf 实例。 pub fn new(from: String, dest: String) -> Self { WebSycnConf { from, dest } } /// 获取源路径。 /// /// # 返回值 /// 返回源路径的引用。 pub fn from(&self) -> &str { &self.from } /// 获取目标路径。 /// /// # 返回值 /// 返回目标路径的引用。 pub fn dest(&self) -> &str { &self.dest } } #[test] fn config_test() { let cvrfsyncer = WebSycnConf::new( "http://mirrors.ustc.edu.cn/openeuler/security/data/cvrf/".to_string(), "./test/cvrfs".to_string(), ); let srpmsyncer = WebSycnConf::new( "http://mirrors.ustc.edu.cn/culinux/3.0/source/".to_string(), "./test/srpms".to_string(), ); let mut config = Config::new(); config.inner.insert("cvrf".to_string(), cvrfsyncer); config.inner.insert("srpms".to_string(), srpmsyncer); let conf_file = "./test/cuwebsyncer.toml"; // 首先测试写入配置文件 match config.save(conf_file) { Ok(()) => assert!(true), Err(e) => assert_eq!("", format!("{e}")), } // 再测试读取 let new_config = Config::load(conf_file).unwrap(); // 两个结果相等 assert_eq!(config, new_config); // 删除测试用文件 std::fs::remove_file(conf_file).unwrap(); }