Files
Unlucky-Launcher/crates/presenter/src/dto/instances/loader.rs
T
AskaEth 0522a41a52
CI / fmt (rustfmt --check) (push) Waiting to run
CI / clippy (ubuntu-latest) (push) Waiting to run
CI / clippy (windows-latest) (push) Waiting to run
CI / test (ubuntu-latest) (push) Waiting to run
CI / test (windows-latest) (push) Waiting to run
CI / build release (ubuntu-latest) (push) Waiting to run
CI / build release (windows-latest) (push) Waiting to run
CI / runtime smoke (ubuntu x64, xvfb) (push) Waiting to run
CI / runtime smoke (macos arm64, probe) (push) Skipped
CI / update-e2e (windows x64) (push) Waiting to run
GPU evidence / GPU 判据自测(不需 GPU;跳过 ≠ 已验证) (push) Waiting to run
GPU evidence / GPU 证据 — 探测可用产物与硬件适配器 (push) Waiting to run
Guards / core 零 UI 守门 (push) Waiting to run
Guards / presenter 零 UI 守门 (push) Waiting to run
Guards / design 零第三方依赖守门 (push) Waiting to run
Guards / unsafe 落点守门(集合必须恰好等于期望) (push) Waiting to run
Guards / 文件行数 ≤400 守门 (push) Waiting to run
Guards / 依赖许可与来源(cargo-deny) (push) Waiting to run
Release guard / 发布标记语义守门(push tag → 稳定版) (push) Waiting to run
Signing status(播报,不是门禁) / 判据自测(三行/退出码/变异重放/接线) (push) Waiting to run
Signing status(播报,不是门禁) / 签名就绪度(播报) (push) Waiting to run
Release / 选槽位(默认四个:Windows 两档 + Linux 两档) (push) Waiting to run
release: v0.2.5
2026-11-12 12:06:59 +08:00

139 lines
4.7 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! 加载器词表(磁贴徽标 + 向导可选)与 [`LoaderInfo`]。
use serde::{Deserialize, Serialize};
use unlucky_core::game::LoaderKind as CoreLoaderKind;
/// 加载器种类(磁贴徽标 + 详情页版本链)。
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum LoaderKind {
/// 原版(无加载器)
Vanilla,
/// Fabric
Fabric,
/// Quilt
Quilt,
/// Forge
Forge,
/// NeoForge
NeoForge,
/// OptiFine
OptiFine,
/// LiteLoader
LiteLoader,
}
impl LoaderKind {
/// 徽标显示文字。
pub fn label(self) -> &'static str {
match self {
Self::Vanilla => "原版",
Self::Fabric => "Fabric",
Self::Quilt => "Quilt",
Self::Forge => "Forge",
Self::NeoForge => "NeoForge",
Self::OptiFine => "OptiFine",
Self::LiteLoader => "LiteLoader",
}
}
/// 本 DTO 种类 → core 的宽种类。
///
/// **结构映射,一个 id 字面量都没有**:词表只有一个真相源
/// ([`CoreLoaderKind::as_str`]),本 crate 写不进第二份。加一支 DTO 种类这里编不过。
const fn to_core(self) -> CoreLoaderKind {
match self {
Self::Vanilla => CoreLoaderKind::Vanilla,
Self::Fabric => CoreLoaderKind::Fabric,
Self::Quilt => CoreLoaderKind::Quilt,
Self::Forge => CoreLoaderKind::Forge,
Self::NeoForge => CoreLoaderKind::NeoForge,
Self::OptiFine => CoreLoaderKind::OptiFine,
Self::LiteLoader => CoreLoaderKind::LiteLoader,
}
}
/// core 的宽种类 → 本 DTO 种类([`Self::to_core`] 的反向,同样不含字面量)。
///
/// core 给 `game::LoaderKind` 加一支、而 DTO 还没跟上时,这里编不过——这正是要的:
/// UI 不许「新加载器默默显示成原版」。
const fn from_core(kind: CoreLoaderKind) -> Self {
match kind {
CoreLoaderKind::Vanilla => Self::Vanilla,
CoreLoaderKind::Fabric => Self::Fabric,
CoreLoaderKind::Quilt => Self::Quilt,
CoreLoaderKind::Forge => Self::Forge,
CoreLoaderKind::NeoForge => Self::NeoForge,
CoreLoaderKind::OptiFine => Self::OptiFine,
CoreLoaderKind::LiteLoader => Self::LiteLoader,
}
}
/// 稳定 id(`vanilla` / `fabric` / …;GUI 与 `--json` 同词表)。
///
/// **委派**给 [`CoreLoaderKind::as_str`](M126):词表的源头表在 core(0.2.0 已发布契约;
/// 另一处逐字副本是 `ull help instances` 的词表行),这里只剩一次结构映射。
#[must_use]
pub fn as_str(self) -> &'static str {
self.to_core().as_str()
}
/// 从稳定 id 解析(未知给 `None`,由调用方决定报错文案)。
///
/// 七个 id 的匹配委派给 [`CoreLoaderKind::parse`];本方法只额外收 `none` / 空串这两个
/// **GUI 输入别名**(表单里「不装加载器」的写法)——它们不是对外输出的 id,也绝不参与
/// [`Self::as_str`]。
pub fn parse(raw: &str) -> Option<Self> {
let wanted = raw.trim();
if wanted.is_empty() || wanted.eq_ignore_ascii_case("none") {
return Some(Self::Vanilla);
}
Some(Self::from_core(CoreLoaderKind::parse(wanted)?))
}
/// 向导里的可选加载器(顺序即展示顺序)。
///
/// 六选 = 原版 + 五家能装的。OptiFine 仍**不在这里**:它要跑外部 `optifine.Patcher` 并原地
/// 改 zip,core 侧至今没有安装路线(见 `DevDocs/artifacts/m218/SURVEY-p1.md` §3),
/// 放进向导只会让用户选完才失败。
pub fn wizard_choices() -> [Self; 6] {
[
Self::Vanilla,
Self::Fabric,
Self::Quilt,
Self::Forge,
Self::NeoForge,
Self::LiteLoader,
]
}
}
/// 加载器 + 版本(例如 Fabric 0.16.5)。
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct LoaderInfo {
/// 加载器种类
pub kind: LoaderKind,
/// 加载器版本号;原版为空串
pub version: String,
}
impl Default for LoaderInfo {
fn default() -> Self {
Self {
kind: LoaderKind::Vanilla,
version: String::new(),
}
}
}
impl LoaderInfo {
/// 徽标文字:原版只写「原版」,装加载器时写「Fabric 0.16.5」。
pub fn badge(&self) -> String {
if self.kind == LoaderKind::Vanilla || self.version.is_empty() {
self.kind.label().to_string()
} else {
format!("{} {}", self.kind.label(), self.version)
}
}
}