refactor(core): M126 加载器稳定 id 词表收敛到 game::LoaderKind::as_str
M122 把「id → 加载器」的解析收到 core::game::loader::InstanceLoader::parse,但 「种类 → 对外稳定 id」的命名词表还散在多处,其中 install 侧那一份只靠一句「不要改名」 的注释约束,MARKERS 更是第四张无守卫字面量表。 - core::game::LoaderKind 新增 as_str(**全仓唯一一份 id 字面量**)、has_marker (穷尽 match:新种类必须表态认不认 id 标记)、parse(as_str 的反查)与 ALL(清单, 顺序即标记优先级);MARKERS 的标记串改为取自 as_str,不再是独立字面量。 - addon::loader::LoaderKind::as_str 改成委派(结构映射,无字面量):安装侧拼出的 <mc>-<kind>-<loader> 与解析侧从此同源。 - presenter::dto::instances::LoaderKind 的 as_str/parse 委派给 core(to_core/from_core 是结构映射),删掉第四份词表;CLI 删掉 loader_kind_id 翻译层,直接调 core。 - 测试:core 新增 markers_cover_every_kind_that_has_one(MARKERS↔ALL↔has_marker↔as_str 逐格对齐 + 按标记串 round-trip + neoforge 先于 forge);presenter 新增 loader_kind_ids_are_the_released_contract(七个 id 逐字钉住 + 反查 + 别名隔离)。 - 对外输出未变:真二进制对同一组 7 类实例的 `instances list --json` 输出逐字节相同 (md5 0341752658ca28e020ba48c31a51a124),人读输出同样逐字节相同。 file 行数:core/game/loader.rs 337→399(≤400 硬约束,文档按密度重排、事实未丢)。
This commit is contained in:
1 parent
84f85bbc79
commit
be37c17962
4 files changed
+253
-134
No files matched your search
@@ -8,8 +8,10 @@
|
||||
//!
|
||||
//! 每一行实例带一个 `loader` 对象:`{"kind": <稳定 id>, "version": <版本段>}`。它是
|
||||
//! **`version_id` 的解析结果**,解析本身不在这里——[`unlucky_core::game::InstanceLoader::parse`]
|
||||
//! 是全仓唯一的 id → 加载器入口(M122 收敛)。CLI 只做「种类 → 稳定 id」的翻译,**不重写
|
||||
//! 任何 id 匹配**:那份规则一旦两处各算一遍就会漂(M120 的「刚装的 Fabric 显示成原版」)。
|
||||
//! 是全仓唯一的 id → 加载器入口(M122 收敛)。种类 → 稳定 id 的词表同样不在本 crate:
|
||||
//! [`unlucky_core::game::LoaderKind::as_str`] 是全仓唯一一份 id 字面量(M126 收敛),这里直接
|
||||
//! 调它,**连翻译层都没有**——词表与 id 匹配一样,两处各算一遍就会漂(M120 的「刚装的
|
||||
//! Fabric 显示成原版」)。
|
||||
//!
|
||||
//! ## 约定一:`loader` 恒存在,原版是 `{"kind":"vanilla","version":""}`
|
||||
//!
|
||||
@@ -44,7 +46,7 @@ use std::path::PathBuf;
|
||||
|
||||
use serde_json::{json, Value};
|
||||
use unlucky_core::game::install::instance::read_profiles as read_profiles_from_layout;
|
||||
use unlucky_core::game::{InstanceLoader, LoaderKind, ProfileList};
|
||||
use unlucky_core::game::{InstanceLoader, ProfileList};
|
||||
|
||||
use crate::context::Ctx;
|
||||
use crate::error::CliError;
|
||||
@@ -128,33 +130,17 @@ fn option_path(path: Option<&PathBuf>) -> Option<String> {
|
||||
|
||||
/// 版本 id → `loader` 对象(`{"kind": …, "version": …}`)。
|
||||
///
|
||||
/// 解析走 [`InstanceLoader::parse`](全仓唯一入口);这里**不写任何 id 匹配**,只把解析结果
|
||||
/// 翻成 JSON。原版同样给出对象(`kind = vanilla`、`version = ""`),不缺键、不为 `null`
|
||||
/// ——见模块文档的「约定一」。
|
||||
/// 解析走 [`InstanceLoader::parse`](全仓唯一入口);种类 → 稳定 id 走
|
||||
/// [`unlucky_core::game::LoaderKind::as_str`](词表的唯一真相源,M126)。这里既**不写 id
|
||||
/// 匹配**,也**不写词表**:两样都只该有一份,且都在 core。原版同样给出对象
|
||||
/// (`kind = vanilla`、`version = ""`),不缺键、不为 `null`——见模块文档的「约定一」。
|
||||
fn loader_json(version_id: &str) -> Value {
|
||||
let parsed = InstanceLoader::parse(version_id);
|
||||
json!({
|
||||
"kind": loader_kind_id(parsed.kind),
|
||||
"kind": parsed.kind.as_str(),
|
||||
"version": parsed.version,
|
||||
})
|
||||
}
|
||||
|
||||
/// 加载器种类 → 稳定 id。
|
||||
///
|
||||
/// 词表与 `--loader` 同源(`vanilla` / `fabric` / `quilt` / `forge` / `neoforge`),另加两个
|
||||
/// **只能识别、不能安装**的 `optifine` / `liteloader`。穷尽 match:core 加一支就编不过,
|
||||
/// 不会静默漏报成 `vanilla`。
|
||||
fn loader_kind_id(kind: LoaderKind) -> &'static str {
|
||||
match kind {
|
||||
LoaderKind::Vanilla => "vanilla",
|
||||
LoaderKind::Fabric => "fabric",
|
||||
LoaderKind::Quilt => "quilt",
|
||||
LoaderKind::Forge => "forge",
|
||||
LoaderKind::NeoForge => "neoforge",
|
||||
LoaderKind::OptiFine => "optifine",
|
||||
LoaderKind::LiteLoader => "liteloader",
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
Reference in new issue
Block a user