diff --git a/adapters/src/unity/adapter.rs b/adapters/src/unity/adapter.rs index 9c1c253..d3f1c5c 100644 --- a/adapters/src/unity/adapter.rs +++ b/adapters/src/unity/adapter.rs @@ -21,11 +21,41 @@ impl VersionRange { } /// 检查版本是否在范围内 + /// + /// 按 `(major, minor, patch)` 数值比较,补丁号允许携带 Unity 发布后缀 + /// (例如 `2021.3.9f1` 按补丁号 9 参与比较);无法解析的版本一律视为不在范围内。 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::().ok()?; + let minor = parts.next()?.parse::().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::().ok()?; + Some((major, minor, patch)) +} + /// 原始 AssetBundle 数据 #[derive(Debug)] pub struct RawAssetBundle { @@ -175,6 +205,40 @@ mod tests { 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] fn test_raw_assetbundle() { let bundle = RawAssetBundle { diff --git a/adapters/src/unity/unity_2021_3.rs b/adapters/src/unity/unity_2021_3.rs index 415dbb3..70e23b2 100644 --- a/adapters/src/unity/unity_2021_3.rs +++ b/adapters/src/unity/unity_2021_3.rs @@ -436,6 +436,7 @@ mod tests { assert!(range.contains("2021.3.0")); assert!(range.contains("2021.3.56")); + assert!(range.contains("2021.3.9f1")); assert!(!range.contains("2021.2.0")); }