diff --git a/src/config.rs b/src/config.rs index e69de29..86f6370 100644 --- a/src/config.rs +++ b/src/config.rs @@ -0,0 +1,141 @@ +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(); +}