diff --git a/.vscode/settings.json b/.vscode/settings.json index 43d62b7..4fb18cc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,5 +14,6 @@ "ureq", "ustc", "wearerequired" - ] + ], + "rust-analyzer.checkOnSave": true } diff --git a/Cargo.toml b/Cargo.toml index 0d13c77..6da3b79 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "crm" -version = "0.2.2" +version = "0.2.3" authors = ["wtklbm "] description = "crm can help you easy and fast switch between different cargo registries, now include: sjtu, tuna, ustc, rsproxy, bfsu, nju, hit, cqu, zju, CERNET." homepage = "https://github.com/wtklbm/crm" repository = "https://github.com/wtklbm/crm.git" -edition = "2018" +edition = "2021" license = "MIT OR Apache-2.0" keywords = ["cargo", "registry"] exclude = [".vscode/**"] @@ -21,5 +21,5 @@ strip = true codegen-units = 512 [dependencies] -toml_edit = "0.2.1" -ureq = "2.1.1" +toml_edit = "0.22.20" +ureq = "2.10.1" diff --git a/README.md b/README.md index 6c54898..caade50 100644 --- a/README.md +++ b/README.md @@ -181,6 +181,33 @@ lazy_static = {version = "1.4.0", registry = "sjtu"} + +## 错误处理 + +以下是 crm 异常结束的情况对照表: +- 1:写入的镜像名称有误 +- 2:写入的镜像地址有误 +- 3:`config.json` 文件的 `dl` 字段值有误 +- 4:命令无效 +- 5:字段不存在(cargo的配置文件有误) +- 6:配置文件解析失败(格式有误或字段缺失) +- 7:要进行下载测试的镜像不存在 +- 8:`REPLACE_WITH` 字段的值缺失 +- 9:配置文件格式错误(字段值无法写入不是表的类型中) +- 10:属性名错误 +- 11:不能删除内置镜像 +- 12:要删除的镜像不存在 +- 13:要进行连接测试的镜像不存在 +- 14:解析配置文件失败 +- 15:字段有误,请参考提示 +- 16:文件的条目中缺少字段,请参考提示 +- 17:字段有误,请参考提示 +- 18:写入文件失败,请检查权限 +- 19:传入的参数错误 +- 20:配置文件冲突,需手动检查 + + + ## Others ### rust-library-chinese @@ -190,9 +217,6 @@ lazy_static = {version = "1.4.0", registry = "sjtu"} - [从 Github 访问](https://github.com/wtklbm/rust-library-i18n) - [从 Gitee 访问](https://gitee.com/wtklbm/rust-library-chinese) - - - ## LICENSE MIT OR Apache-2.0 diff --git a/src/cargo.rs b/src/cargo.rs index d8d194b..5041bea 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -5,7 +5,7 @@ use std::process; -use toml_edit::{table, value, Table}; +use toml_edit::{table, value, Item, Table}; use crate::{ constants::{ @@ -19,17 +19,18 @@ use crate::{ /// 验证字段是否存在 fn verify_field_exists(data: &mut Table, key: &str) { - let value = &data[key]; - - if value.is_none() { + if data.contains_key(key) { + if !data[key].is_table() { + field_eprint(key, TABLE); + process::exit(5); + } + } else { data[key] = table(); - } else if !value.is_table() { - field_eprint(key, TABLE); - process::exit(5); - } + }; } /// `Cargo` 配置对象 +#[derive(Debug)] pub struct CargoConfig { /// 配置对象中的数据,它是一个经过反序列化的对象 data: Toml, @@ -73,15 +74,14 @@ impl CargoConfig { /// 如果 `Cargo` 配置文件中不包含 `[source.crates-io]` 属性,则为 `Cargo` 配置自动填充。 fn fill_crates_io(&mut self) { - let data = self.data.table_mut(); - let crates_io = &data[SOURCE][CRATES_IO]; + let data: &mut Table = self.data.table_mut(); - if crates_io.is_none() { - data[SOURCE][CRATES_IO] = table(); - } else if !crates_io.is_table() { - field_eprint(CRATES_IO, TABLE); - process::exit(7); - } + if data.contains_table(SOURCE) { + let source: &mut Table = data[SOURCE].as_table_mut().unwrap(); + if !source.contains_key(CRATES_IO) { + data[SOURCE][CRATES_IO] = table(); + } + }; } /// 如果切换为默认镜像时,则删除 `replace_with` 属性。否则, @@ -90,8 +90,8 @@ impl CargoConfig { fn replace_with(&mut self, registry_name: &str) { self.fill_crates_io(); - let data = self.data.table_mut(); - let crates_io = &mut data[SOURCE][CRATES_IO]; + let data: &mut Table = self.data.table_mut(); + let crates_io: &mut Item = &mut data[SOURCE][CRATES_IO]; // 去除属性 if registry_name.eq(RUST_LANG) && !crates_io.is_none() { @@ -106,11 +106,11 @@ impl CargoConfig { /// 从 `Cargo` 配置文件中获取正在使用的镜像,其中 `rust-lang` 是 `Cargo` 默认使用的镜像。 pub fn current(&mut self) -> (String, Option) { let data = self.data.table_mut(); - let replace_with = &data[SOURCE][CRATES_IO][REPLACE_WITH]; // 从配置文件中获取镜像名 - let name = if !replace_with.is_none() { - match replace_with.as_str() { + let source = data[SOURCE][CRATES_IO].as_table().unwrap(); + let name = if source.contains_key(REPLACE_WITH) { + match source[REPLACE_WITH].as_value().unwrap().as_str() { Some(name) => name, None => { field_eprint(REPLACE_WITH, STRING); @@ -129,17 +129,18 @@ impl CargoConfig { /// 追加属性 fn append_attribute(&mut self, key: &str, registry_name: &str, addr: &str) { - let config = self.data.table_mut(); - let source = &mut config[key]; - let registry = &source[registry_name]; - - // 如果没有 `[source.xxx]` 属性 - if registry.is_none() { - source[registry_name] = table(); - } else if !registry.is_table() { - field_eprint(registry_name, TABLE); - process::exit(9); - } + let config: &mut Table = self.data.table_mut(); + let source: &mut Item = &mut config[key]; + + match source.get(registry_name) { + Some(x) => { + if !x.is_table() { + field_eprint(registry_name, TABLE); + process::exit(9); + } + } + None => source[registry_name] = table(), + }; let attr = match key { SOURCE => REGISTRY, @@ -176,12 +177,13 @@ impl CargoConfig { return; } - let source = &mut self.data.table_mut()[key]; + let source: &mut Item = &mut self.data.table_mut()[key]; // 如果没有 `[source.xxx]` 属性 - if source[registry_name].is_none() { - return; - } + match source.get(registry_name) { + Some(_) => (), + None => return, + }; source .as_table_mut() diff --git a/src/constants.rs b/src/constants.rs index ae6e686..6b3a1f3 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -100,7 +100,7 @@ dl = "https://mirror.sjtu.edu.cn/crates.io/crates/{crate}/{crate}-{version}.crat # 中科大 [source.ustc] -registry = "git://mirrors.ustc.edu.cn/crates.io-index" +registry = "https://mirrors.ustc.edu.cn/crates.io-index" dl = "https://crates-io.proxy.ustclug.org/api/v1/crates" # 中科大 - sparse diff --git a/src/registry.rs b/src/registry.rs index ddafc0c..48a0d18 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -218,8 +218,8 @@ impl Registry { let urls = match name { Some(name) => { if self.rc.get(name).is_none() { - to_out(format!("测试失败,{} 镜像不存在", name)); - process::exit(13); + to_out(format!("下载测试失败,{} 镜像不存在", name)); + process::exit(7); } vec![(name.to_string(), self.to_download_url(name))] @@ -260,7 +260,7 @@ impl Registry { let urls = match name { Some(name) => { if self.rc.get(name).is_none() { - to_out(format!("测试失败,{} 镜像不存在", name)); + to_out(format!("连接测试失败,{} 镜像不存在", name)); process::exit(13); } diff --git a/src/runtime.rs b/src/runtime.rs index 0496f60..9eed3da 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -11,7 +11,7 @@ use std::{ process, }; -use toml_edit::{table, value}; +use toml_edit::{table, value, Item, Table}; use crate::{ constants::{ @@ -165,19 +165,19 @@ impl RuntimeConfig { } let mut config = config.unwrap(); - let data = config.table_mut(); - let source = &data[SOURCE]; - - // 如果没有则创建表,否则判断是不是表 - if source.is_none() { + let data: &mut Table = config.table_mut(); + if data.contains_key(SOURCE) { + let source: &Item = &data[SOURCE]; + if !source.is_table() { + to_out(format!( + "{} 文件中的 {} 字段不是一个{},{}", + CRMRC_PATH, SOURCE, TABLE, PLEASE_TRY + )); + process::exit(15); + } + } else { data[SOURCE] = table(); - } else if !source.is_table() { - to_out(format!( - "{} 文件中的 {} 字段不是一个{},{}", - CRMRC_PATH, SOURCE, TABLE, PLEASE_TRY - )); - process::exit(15); - } + }; config } diff --git a/src/toml.rs b/src/toml.rs index fd0fddf..9c5373b 100644 --- a/src/toml.rs +++ b/src/toml.rs @@ -8,20 +8,20 @@ use std::{ process, }; -use toml_edit::{Document, Table, TomlError}; +use toml_edit::{DocumentMut, Table, TomlError}; use crate::utils::to_out; #[derive(Debug)] pub struct Toml { /// 文档 - pub doc: Document, + pub doc: DocumentMut, } impl Toml { /// 解析 `toml` 字符串 pub fn parse(input: &str) -> Result { - match input.parse::() { + match input.parse::() { Ok(doc) => Ok(Toml { doc }), Err(e) => Err(e), } @@ -39,7 +39,7 @@ impl Toml { /// 转换为字符串 pub fn toml_string(&self) -> String { - self.doc.to_string_in_original_order().trim().to_string() + self.doc.to_string().trim().to_string() } /// 写入到文件中