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:
AskaEth committed 2026-11-05 18:08:56 +08:00
1 parent 84f85bbc79
commit be37c17962
4 files changed
+253 -134

No files matched your search

+10 -5
View File
@@ -74,14 +74,19 @@ impl LoaderKind {
}
}
/// 稳定字符串 id(进版本 id、JSON 输出与日志,**不要改名**)。
/// 稳定字符串 id(进版本 id、JSON 输出与日志)。
///
/// 词表**不在本模块**:[`crate::game::LoaderKind::as_str`] 是「种类 → 对外稳定 id」的唯一
/// 真相源(M126)。这里只做**结构映射**(一个 id 字面量都没有)——安装侧拼出来的
/// `<mc>-<kind>-<loader>` 必须能被 [`crate::game::InstanceLoader::parse`] 认回来,委派让
/// 「两边各写一份、改一边忘了另一边」这件事物理上做不到。
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Fabric => "fabric",
Self::Quilt => "quilt",
Self::NeoForge => "neoforge",
Self::Forge => "forge",
Self::Fabric => crate::game::LoaderKind::Fabric.as_str(),
Self::Quilt => crate::game::LoaderKind::Quilt.as_str(),
Self::NeoForge => crate::game::LoaderKind::NeoForge.as_str(),
Self::Forge => crate::game::LoaderKind::Forge.as_str(),
}
}