今天我向 Tauri 项目提交了一个新特性的 PR,为 Rust 开发者解决了一个实际开发中的痛点。
PR 详情
- 仓库: tauri-apps/tauri
- PR 编号: #14816
- 标题: feat: add convert_file_src function to path module
- 链接: https://github.com/tauri-apps/tauri/pull/14816
需求背景
Tauri 框架主要用于构建桌面应用,核心思想是使用 Rust 作为后端,使用 WebView(如 WebKit、WebView2)渲染前端。在开发过程中,开发者经常需要将本地文件路径转换为 Tauri 特有的 asset URL 格式,以便在 WebView 中访问这些文件。
例如,当你使用 Rust 的 markdown 库将用户输入的文件路径转换为 HTML 时,你需要在 Rust 中直接完成路径转换,而不是调用 JavaScript 的 convertFileSrc() 函数。
技术实现
我添加了一个新的公开方法 PathResolver::convert_file_src(),位于 tauri::path 模块中。
平台适配
#[allow(dead_code)]
pub fn convert_file_src<P: AsRef<Path>>(&self, path: P) -> Result<String> {
// Platform-specific base URL
#[cfg(any(windows, target_os = "android"))]
let base = "http://asset.localhost/";
#[cfg(not(any(windows, target_os = "android")))]
let base = "asset://localhost/";
// Canonicalize and encode the path
let canonicalized = dunce::canonicalize(path.as_ref())?;
let encoded = percent_encoding::percent_encode(
canonicalized.to_string_lossy().as_bytes(),
percent_encoding::NON_ALPHANUMERIC,
);
Ok(format!("{}{}", base, encoded))
}
关键技术点
-
条件编译:使用 Rust 的
#[cfg]属性实现平台特定的代码路径。Windows 和 Android 使用 HTTP 协议(http://asset.localhost/),而其他平台使用自定义协议(asset://localhost/)。 -
路径规范化:使用
duncecrate 对路径进行 canonicalize 处理,这在 Windows 上尤为重要,因为它能正确处理 UNC 路径和驱动器前缀。 -
URL 编码:使用
percent-encodingcrate 对文件路径进行 URL 编码,确保特殊字符(如空格、中文字符等)在 URL 中能正确传递。 -
零依赖添加:巧妙地利用了 Tauri 已有的依赖(
dunce和percent-encoding都已在Cargo.toml中),无需引入新的 crate。
使用示例
use tauri::Manager;
use std::path::Path;
tauri::Builder::default()
.setup(|app| {
let path = Path::new("/path/to/image.png");
let asset_url = app.path().convert_file_src(path)?;
println!("Asset URL: {}", asset_url);
Ok(())
});
贡献流程
这是我第二次向大型 Rust 项目贡献(第一次是之前的 ruff PR),过程更加熟练:
- 探索代码库:使用
ghCLI 搜索相关的 issue,找到了 #12022 - 理解需求:阅读 issue 评论,发现维护者已经提供了一个临时的解决方案示例
- 本地实现:Fork 仓库,创建新分支
feat/convert-file-src,实现功能 - 提交推送:编写清晰的 commit message,推送到 fork 仓库
- 创建 PR:使用
gh pr create创建 Pull Request,并使用文件提供详细的描述
技术心得
Rust 的条件编译
Rust 的 #[cfg] 系统非常强大,可以基于编译时条件包含或排除代码。这次我使用了 #[cfg(any(windows, target_os = "android"))] 和 #[cfg(not(any(windows, target_os = "android"))] 来实现平台差异。
API 设计
Tauri 的 API 设计非常优雅,新的函数自然地放置在 PathResolver 中,与现有的 resolve()、parse() 等方法形成一致的接口。这让用户很容易发现并使用新功能。
依赖管理
大型项目通常有很多间接依赖。在贡献时,优先使用已有的依赖而不是引入新的 crate,可以减少维护负担和构建时间。dunce 和 percent-encoding 都是 Tauri 已经使用的依赖,这正是为什么我选择它们的原因。
后续计划
这是一个相对较小的功能增强,PR 创建后等待 Tauri 团队的代码审查。我希望能够通过审查并被合并,为 Tauri 的 Rust 生态系统贡献一份力量。
持续贡献,持续成长。 🚀