refactor: address quality findings

This commit is contained in:
2026-06-28 13:04:53 +08:00
parent b202d7b231
commit 02716d3ccd
4 changed files with 120 additions and 78 deletions
+57 -52
View File
@@ -16,6 +16,59 @@ impl AddressablesCatalogDriver {
pub fn new() -> Self {
Self
}
fn parse_json(raw_data: &[u8]) -> Result<Value, String> {
let text = std::str::from_utf8(raw_data).map_err(|e| format!("Invalid UTF-8: {}", e))?;
serde_json::from_str(text).map_err(|e| format!("Invalid JSON: {}", e))
}
fn locator_id(json: &Value) -> Option<String> {
json.get("m_LocatorId")
.and_then(|value| value.as_str())
.map(ToOwned::to_owned)
}
fn cdn_prefixes(json: &Value) -> Vec<String> {
json.get("m_InternalIdPrefixes")
.and_then(|value| value.as_array())
.into_iter()
.flatten()
.filter_map(|value| value.as_str())
.map(ToOwned::to_owned)
.collect()
}
fn resource_type_for_path(path: &str) -> ResourceType {
if path.ends_with(".bundle") {
ResourceType::AssetBundle
} else if path.contains("catalog") {
ResourceType::Manifest
} else {
ResourceType::Other
}
}
fn resources(json: &Value) -> Vec<ResourceEntry> {
json.get("m_InternalIds")
.and_then(|value| value.as_array())
.into_iter()
.flatten()
.enumerate()
.filter_map(|(index, value)| {
let path = value.as_str()?;
if path.is_empty() {
return None;
}
Some(ResourceEntry {
path: path.to_string(),
hash: format!("addressable_{}", index),
size: 0,
resource_type: Self::resource_type_for_path(path),
})
})
.collect()
}
}
impl Default for AddressablesCatalogDriver {
@@ -64,69 +117,21 @@ impl ManifestDriver for AddressablesCatalogDriver {
}
async fn parse(&self, raw_data: &[u8]) -> Result<GenericManifest, String> {
// 解析 JSON
let text = std::str::from_utf8(raw_data).map_err(|e| format!("Invalid UTF-8: {}", e))?;
let json: Value = serde_json::from_str(text).map_err(|e| format!("Invalid JSON: {}", e))?;
// 提取元数据
let locator_id = json
.get("m_LocatorId")
.and_then(|v| v.as_str())
.map(|s| s.to_string());
// 提取 CDN 前缀
let mut cdn_prefixes = Vec::new();
if let Some(prefixes) = json.get("m_InternalIdPrefixes").and_then(|v| v.as_array()) {
for prefix in prefixes {
if let Some(s) = prefix.as_str() {
cdn_prefixes.push(s.to_string());
}
}
}
// 提取资源列表(基础版本 - 仅从 m_InternalIds 提取)
let mut resources = Vec::new();
if let Some(internal_ids) = json.get("m_InternalIds").and_then(|v| v.as_array()) {
for (index, id) in internal_ids.iter().enumerate() {
if let Some(path) = id.as_str() {
// 跳过空路径
if path.is_empty() {
continue;
}
// 判断资源类型
let resource_type = if path.ends_with(".bundle") {
ResourceType::AssetBundle
} else if path.contains("catalog") {
ResourceType::Manifest
} else {
ResourceType::Other
};
resources.push(ResourceEntry {
path: path.to_string(),
hash: format!("addressable_{}", index), // 临时 Hash
size: 0, // 大小未知
resource_type,
});
}
}
}
let json = Self::parse_json(raw_data)?;
// TODO: 解析 m_KeyDataString、m_EntryDataString 等压缩字段
// 这些字段使用了自定义压缩格式,需要实现解压缩算法
// 参考:Unity Addressables 源代码
let metadata = ManifestMetadata {
locator_id,
cdn_prefixes,
locator_id: Self::locator_id(&json),
cdn_prefixes: Self::cdn_prefixes(&json),
extra: HashMap::new(),
};
Ok(GenericManifest {
format: ManifestFormat::AddressablesCatalog,
resources,
resources: Self::resources(&json),
metadata,
})
}