mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-07-22 04:06:44 +08:00
fix(adapters): 按数值比较 Unity 版本范围
VersionRange::contains 原为字符串字典序比较,2021.3.9f1 等带发布后缀的 正式版本会被 can_handle/parse 误拒,多位补丁号排序也不正确。改为解析 (major, minor, patch) 数值元组比较,补丁号剥离发布后缀,无法解析的版本 一律视为不在范围内,并补充多位补丁号、后缀版本和畸形版本的测试。 对应 issue #18 维护清单 1-1。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,9 +21,39 @@ impl VersionRange {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 检查版本是否在范围内
|
/// 检查版本是否在范围内
|
||||||
|
///
|
||||||
|
/// 按 `(major, minor, patch)` 数值比较,补丁号允许携带 Unity 发布后缀
|
||||||
|
/// (例如 `2021.3.9f1` 按补丁号 9 参与比较);无法解析的版本一律视为不在范围内。
|
||||||
pub fn contains(&self, version: &str) -> bool {
|
pub fn contains(&self, version: &str) -> bool {
|
||||||
version >= self.min.as_str() && version <= self.max.as_str()
|
match (
|
||||||
|
parse_version_components(version),
|
||||||
|
parse_version_components(&self.min),
|
||||||
|
parse_version_components(&self.max),
|
||||||
|
) {
|
||||||
|
(Some(version), Some(min), Some(max)) => version >= min && version <= max,
|
||||||
|
_ => false,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 将 Unity 版本字符串解析为 `(major, minor, patch)` 数值元组。
|
||||||
|
///
|
||||||
|
/// `major`/`minor` 必须是纯数字;`patch` 取第三段的前导数字,
|
||||||
|
/// 以兼容 `2021.3.9f1` 这类带发布后缀的正式版本号。
|
||||||
|
fn parse_version_components(version: &str) -> Option<(u64, u64, u64)> {
|
||||||
|
let mut parts = version.split('.');
|
||||||
|
let major = parts.next()?.parse::<u64>().ok()?;
|
||||||
|
let minor = parts.next()?.parse::<u64>().ok()?;
|
||||||
|
let patch_part = parts.next()?;
|
||||||
|
let digit_count = patch_part
|
||||||
|
.chars()
|
||||||
|
.take_while(|character| character.is_ascii_digit())
|
||||||
|
.count();
|
||||||
|
if digit_count == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let patch = patch_part[..digit_count].parse::<u64>().ok()?;
|
||||||
|
Some((major, minor, patch))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 原始 AssetBundle 数据
|
/// 原始 AssetBundle 数据
|
||||||
@@ -175,6 +205,40 @@ mod tests {
|
|||||||
assert!(!range.contains("2021.4.0"));
|
assert!(!range.contains("2021.4.0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_version_range_compares_patch_numerically() {
|
||||||
|
let range = VersionRange::new("2021.3.0", "2021.3.99");
|
||||||
|
|
||||||
|
assert!(!range.contains("2021.3.100"));
|
||||||
|
assert!(range.contains("2021.3.9"));
|
||||||
|
|
||||||
|
let wide_range = VersionRange::new("2021.3.20", "2021.3.120");
|
||||||
|
assert!(wide_range.contains("2021.3.100"));
|
||||||
|
assert!(!wide_range.contains("2021.3.9"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_version_range_accepts_release_suffix() {
|
||||||
|
let range = VersionRange::new("2021.3.0", "2021.3.99");
|
||||||
|
|
||||||
|
assert!(range.contains("2021.3.9f1"));
|
||||||
|
assert!(range.contains("2021.3.56f2"));
|
||||||
|
assert!(range.contains("2021.3.99f1"));
|
||||||
|
assert!(!range.contains("2021.3.100f1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_version_range_rejects_malformed_versions() {
|
||||||
|
let range = VersionRange::new("2021.3.0", "2021.3.99");
|
||||||
|
|
||||||
|
assert!(!range.contains(""));
|
||||||
|
assert!(!range.contains("unknown"));
|
||||||
|
assert!(!range.contains("2021"));
|
||||||
|
assert!(!range.contains("2021.3"));
|
||||||
|
assert!(!range.contains("2021.x.5"));
|
||||||
|
assert!(!range.contains("2021.3.f1"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_raw_assetbundle() {
|
fn test_raw_assetbundle() {
|
||||||
let bundle = RawAssetBundle {
|
let bundle = RawAssetBundle {
|
||||||
|
|||||||
@@ -436,6 +436,7 @@ mod tests {
|
|||||||
|
|
||||||
assert!(range.contains("2021.3.0"));
|
assert!(range.contains("2021.3.0"));
|
||||||
assert!(range.contains("2021.3.56"));
|
assert!(range.contains("2021.3.56"));
|
||||||
|
assert!(range.contains("2021.3.9f1"));
|
||||||
assert!(!range.contains("2021.2.0"));
|
assert!(!range.contains("2021.2.0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user