mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-09-18 08:54:55 +08:00
fix(repository): 扩展资源索引查询面
This commit is contained in:
@@ -37,7 +37,7 @@ use async_trait::async_trait;
|
||||
|
||||
/// 资源查询条件
|
||||
///
|
||||
/// 用于构建灵活的资源查询。支持按类型、Hash、路径模式过滤。
|
||||
/// 用于构建灵活的资源查询。支持按类型、Hash、路径、官方 release 和解析摘要过滤。
|
||||
///
|
||||
/// # 示例
|
||||
///
|
||||
@@ -56,9 +56,10 @@ use async_trait::async_trait;
|
||||
/// resource_type: Some(ResourceType::AssetBundle),
|
||||
/// hash: Some("abc123".to_string()),
|
||||
/// path_pattern: Some("academy-*.bundle".to_string()),
|
||||
/// ..ResourceQuery::all()
|
||||
/// };
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ResourceQuery {
|
||||
/// 按资源类型过滤
|
||||
///
|
||||
@@ -90,6 +91,41 @@ pub struct ResourceQuery {
|
||||
/// - `"**/*.json"` - 匹配所有 JSON 文件
|
||||
/// - `"assets/???.png"` - 匹配三个字符的 PNG 文件
|
||||
pub path_pattern: Option<String>,
|
||||
|
||||
/// 按官方 release ID 过滤。
|
||||
///
|
||||
/// 匹配 `ResourceMetadata::official_release_id`。
|
||||
pub official_release_id: Option<String>,
|
||||
|
||||
/// 按资源平台过滤。
|
||||
///
|
||||
/// 匹配 `ResourceMetadata::platform`,例如 `windows` 或 `android`。
|
||||
pub platform: Option<String>,
|
||||
|
||||
/// 按官方 destination 过滤。
|
||||
///
|
||||
/// 匹配 `ResourceEntry::path`,用于从 release manifest destination 反查资源。
|
||||
pub destination: Option<String>,
|
||||
|
||||
/// 按资源或所在 bundle 的官方相对路径过滤。
|
||||
///
|
||||
/// 匹配 `ResourceMetadata::bundle_path`。
|
||||
pub bundle_path: Option<String>,
|
||||
|
||||
/// 按 ZIP/archive entry 过滤。
|
||||
///
|
||||
/// 匹配 `ResourceMetadata::archive_entries` 中的任意一项。
|
||||
pub archive_entry: Option<String>,
|
||||
|
||||
/// 按解析状态过滤。
|
||||
///
|
||||
/// 匹配 `ResourceMetadata::parse_statuses` 中的任意一项。
|
||||
pub parse_status: Option<String>,
|
||||
|
||||
/// 按 TextUnit payload format 过滤。
|
||||
///
|
||||
/// 匹配 `ResourceMetadata::text_unit_formats` 中的任意一项。
|
||||
pub text_unit_format: Option<String>,
|
||||
}
|
||||
|
||||
impl ResourceQuery {
|
||||
@@ -105,11 +141,7 @@ impl ResourceQuery {
|
||||
/// let all_resources = repo.list(ResourceQuery::all()).await?;
|
||||
/// ```
|
||||
pub fn all() -> Self {
|
||||
Self {
|
||||
resource_type: None,
|
||||
hash: None,
|
||||
path_pattern: None,
|
||||
}
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// 按类型查询
|
||||
@@ -132,8 +164,7 @@ impl ResourceQuery {
|
||||
pub fn by_type(resource_type: ResourceType) -> Self {
|
||||
Self {
|
||||
resource_type: Some(resource_type),
|
||||
hash: None,
|
||||
path_pattern: None,
|
||||
..Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,11 +187,23 @@ impl ResourceQuery {
|
||||
/// ```
|
||||
pub fn by_hash(hash: String) -> Self {
|
||||
Self {
|
||||
resource_type: None,
|
||||
hash: Some(hash),
|
||||
path_pattern: None,
|
||||
..Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// 是否包含需要读取完整 `Resource` 后才能判断的条件。
|
||||
///
|
||||
/// 基础索引可先用类型、hash、路径模式和 destination 缩小范围;这些条件
|
||||
/// 需要再按 metadata 过滤,确保 `list()` 与 `count()` 的语义一致。
|
||||
pub fn requires_resource_scan(&self) -> bool {
|
||||
self.official_release_id.is_some()
|
||||
|| self.platform.is_some()
|
||||
|| self.bundle_path.is_some()
|
||||
|| self.archive_entry.is_some()
|
||||
|| self.parse_status.is_some()
|
||||
|| self.text_unit_format.is_some()
|
||||
}
|
||||
}
|
||||
|
||||
/// 资源仓储接口
|
||||
@@ -305,6 +348,7 @@ pub trait ResourceRepository: Send + Sync {
|
||||
/// resource_type: Some(ResourceType::AssetBundle),
|
||||
/// path_pattern: Some("academy-*.bundle".to_string()),
|
||||
/// hash: None,
|
||||
/// ..ResourceQuery::all()
|
||||
/// };
|
||||
/// let filtered = repo.list(query).await?;
|
||||
/// ```
|
||||
@@ -416,6 +460,13 @@ mod tests {
|
||||
assert!(query.resource_type.is_none());
|
||||
assert!(query.hash.is_none());
|
||||
assert!(query.path_pattern.is_none());
|
||||
assert!(query.official_release_id.is_none());
|
||||
assert!(query.platform.is_none());
|
||||
assert!(query.destination.is_none());
|
||||
assert!(query.bundle_path.is_none());
|
||||
assert!(query.archive_entry.is_none());
|
||||
assert!(query.parse_status.is_none());
|
||||
assert!(query.text_unit_format.is_none());
|
||||
}
|
||||
|
||||
/// 测试按类型查询
|
||||
@@ -425,6 +476,7 @@ mod tests {
|
||||
assert_eq!(query.resource_type, Some(ResourceType::AssetBundle));
|
||||
assert!(query.hash.is_none());
|
||||
assert!(query.path_pattern.is_none());
|
||||
assert!(!query.requires_resource_scan());
|
||||
}
|
||||
|
||||
/// 测试按 Hash 查询
|
||||
@@ -434,6 +486,7 @@ mod tests {
|
||||
assert_eq!(query.hash, Some("abc123".to_string()));
|
||||
assert!(query.resource_type.is_none());
|
||||
assert!(query.path_pattern.is_none());
|
||||
assert!(!query.requires_resource_scan());
|
||||
}
|
||||
|
||||
/// 测试组合查询
|
||||
@@ -443,11 +496,32 @@ mod tests {
|
||||
resource_type: Some(ResourceType::AssetBundle),
|
||||
hash: Some("hash123".to_string()),
|
||||
path_pattern: Some("*.bundle".to_string()),
|
||||
official_release_id: Some("v-current".to_string()),
|
||||
platform: Some("windows".to_string()),
|
||||
destination: Some("Bundles/academy.bundle".to_string()),
|
||||
bundle_path: Some("Bundles/academy.bundle".to_string()),
|
||||
archive_entry: Some("academy".to_string()),
|
||||
parse_status: Some("parsed".to_string()),
|
||||
text_unit_format: Some("json".to_string()),
|
||||
};
|
||||
|
||||
assert_eq!(query.resource_type, Some(ResourceType::AssetBundle));
|
||||
assert_eq!(query.hash, Some("hash123".to_string()));
|
||||
assert_eq!(query.path_pattern, Some("*.bundle".to_string()));
|
||||
assert_eq!(query.official_release_id, Some("v-current".to_string()));
|
||||
assert_eq!(query.platform, Some("windows".to_string()));
|
||||
assert_eq!(
|
||||
query.destination,
|
||||
Some("Bundles/academy.bundle".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
query.bundle_path,
|
||||
Some("Bundles/academy.bundle".to_string())
|
||||
);
|
||||
assert_eq!(query.archive_entry, Some("academy".to_string()));
|
||||
assert_eq!(query.parse_status, Some("parsed".to_string()));
|
||||
assert_eq!(query.text_unit_format, Some("json".to_string()));
|
||||
assert!(query.requires_resource_scan());
|
||||
}
|
||||
|
||||
/// 测试 ResourceQuery 可以被克隆
|
||||
|
||||
Reference in New Issue
Block a user