CarParser
CarParser 是一个用于解析 Apple .car asset catalog 文件的 Rust workspace,包含高层 Rust API、命令行工具、WASM 包装层和浏览器本地解码界面。
项目当前重点是读取 CoreUI .car 归档、列出资源、查询变体、解析元数据、导出可用资源,并在浏览器内完成本地预览和下载。浏览器界面只读取本地文件,不上传服务器。
功能
- 解析 Apple BOM 和
.car内部 rendition 数据。 - 提供
carcrate 作为稳定高层 API。 - 支持按 Facet、Rendition、scale、idiom、display gamut 等属性查询资源变体。
- 支持诊断报告,统计 unsupported output、internal reference、unknown TLV 等问题。
- 支持导出 PNG、JPEG、WEBP、HEIF、PDF、SVG、原始数据和颜色 JSON。
- 支持解码常见 raster payload,包括 ARGB、ARGB16、GRAY、GA8、GA16、RGB5、JPEG、WEBP,以及 Deepmap2 相关 payload。
- 提供
car-cli命令用于查看归档信息和批量导出资源。 - 提供
car-wasm和car-web-decoder-site,用于浏览器内解析、预览、搜索、单项下载和 ZIP 批量下载。
目录
| 路径 | 说明 |
|---|---|
bom/ |
Apple BOM 读取和底层模型。 |
deepmap2/ |
Deepmap2 解码相关实现。 |
util/ |
压缩和共享工具。 |
car/ |
主库 crate。公开 API 在 car/src/lib.rs。 |
car-cli/ |
info 和 extract 命令。 |
car-wasm/ |
wasm-bindgen 包装层和 JS worker/client bridge。 |
car-web-decoder-site/ |
Vite、React、TypeScript、Tailwind 浏览器解码站点。 |
car-tests/ |
Rust 集成测试和测试 fixture。 |
test-support/ |
测试辅助 crate。 |
环境
- Rust toolchain,项目使用 Rust edition 2024。
- Node.js 和 pnpm,用于
car-web-decoder-site/。 wasm-pack,用于构建car-wasm。Web 项目的predev、prebuild、pretest*会自动调用pnpm refresh:wasm,该脚本依赖 PATH 中存在wasm-pack。
快速开始
构建默认 workspace members,当前为 car-parser-bom、car-parser-deepmap2 和 car-parser:
运行默认测试:
运行指定 crate 测试:
查看 .car 信息:
导出 .car 资源:
info 输出 JSON,结构接近 assetutil -I。extract 会创建输出目录,默认跳过已有文件,使用 --overwrite 覆盖已有文件。
Rust API
car crate 是主要入口。默认构建不启用图片写出 helper;需要 car::image 时启用 image feature。
图片导出 helper:
更多示例在 car/examples/:
list_entries.rs:列出高层资源条目。query_variant.rs:按属性查询最佳变体。export_plan.rs:查看确定性导出计划。export_png.rs:启用imagefeature 后导出 PNG。export_original.rs:导出原始 payload。diagnostics.rs:输出诊断摘要。
CLI
car-cli 暴露两个子命令:
导出规则由 car::export::plan_export 统一规划:
- 图片类 ThemeCBCK payload 会按可解码格式保存,必要时转成 PNG。
- JPEG、WEBP、SVG、PDF、HEIF 和
Datapayload 尽量保留原始格式。 - Color rendition 导出为 JSON,包含 color space 和 components。
- Multisize image set 导出为 JSON。
- InternalReference 会解析到实际 payload,并应用 crop 信息。
- 输出路径会清理不安全路径片段,并为重名文件生成唯一后缀。
Web Decoder
浏览器解码站点在 car-web-decoder-site/:
生产构建和测试:
站点功能:
- 拖放或选择单个
.car文件。 - 展示 document metadata、资源列表、搜索、详情和高级参数。
- 支持
img-binary、canvas-rgba、color-swatch预览。 - 对 PDF、HEIF、RawData 等资源提供下载路径。
- 支持下载当前资源和 ZIP 批量下载。
- 支持中英文和亮色、暗色、跟随系统主题。
WASM
car-wasm 提供 WasmArchive 和浏览器 worker client。Web 站点通过 alias @car-wasm/client 指向 car-wasm/js/client.js。
可用能力包括:
documentInfo()listEntries()/listEntrySummaries()listImages()/listImageSummaries()getEntryInfo(id)/getImageInfo(id)getDisplayPayload(id)getDownloadPayload(id)getThumbnailPayload(id, { maxDimension })
完整检查接口与旧预览列表分开,旧接口的 ID 和 payload 形态保持兼容:
listAssets()/getAssetInfo(assetId)返回成功加载后全部 facet 条目,使用独立的asset-NID;legacy_entry_id关联旧条目,不保证可预览。variantsFor(assetId)/variantsForName(name)/bestVariantForName(name, query)支持 scale、idiom、displayGamut、appearance、localization、horizontalSizeClass 和 verticalSizeClass。getRenditionInfo(target)/renditionInfos()提供 logical/resolved 元数据、完整属性、TLV 和结构化引用错误;diagnostics()返回无截断的完整诊断,diagnosticsSummary()保留旧摘要。decodeData(target, options?)返回底层解码数据;其中 image 数据不保证为 RGBA 或图片文件。sourceBytes(target)读取解析引用后的源数据,rgbaBytes()/pngBytes()返回带真实尺寸的转换结果。planExport()/getExportPayload(jobId)提供安全相对路径、跳过原因、同源合并和单任务 bytes,不写文件。浏览器边界拒绝含反斜杠的路径,并以unsafe-file-name记录,避免跨平台分隔符歧义。archiveMetadata()/listFacets()/getRenditionRaw(target)提供底层检查。raw 仅公开解析器保留的字段和 payload,不重建丢弃的字节;完整目录不包含孤立 rendition 或损坏文件部分恢复。
target 为互斥的 { assetId: "asset-0" } 或 { keyValues: [...] },后者可以检查 facet 外的引用来源。新增结果的所有二进制字段(含嵌套 payload)均为 Uint8Array;普通元数据只包含 payload 长度。
解码选项为 { maxOutputBytes?, orientationPolicy?: "ignore" | "apply-exif" },默认不限制输出、忽略 EXIF。预算为非负 u32 整数,沿用底层解码和图像转换阶段检查,不是峰值/累计内存或编码文件大小限制。RGBA/PNG 先按原图坐标应用引用裁剪,再应用方向;支持范围沿用 car::image,不额外渲染 SVG/PDF/HEIF 或二次解码 RawData。native 回退与系统 ICC 限制保持不变。
共享具体 TypeScript 类型在 car-wasm/js/client.d.ts 和 api-types.d.ts;生成的 WasmArchive 同步提供类型。Worker/client 保留错误的 code、message 和结构化 details。
刷新 WASM 包:
该命令会在 car-wasm/ 下执行:
测试
Rust:
Web:
部分完整 fixture 测试需要额外样本。启用方式:
CAR_TEST_FULL=1