Back to Blog

为 Tauri 添加 Rust 原生文件路径转换函数

Rust
Open Source
Tauri

为 Tauri 项目添加 convert_file_src 函数,解决了在 Rust 中处理文件路径到 Tauri asset URL 的转换需求。

Published on 1/24/2026

今天我向 Tauri 项目提交了一个新特性的 PR,为 Rust 开发者解决了一个实际开发中的痛点。

PR 详情

需求背景

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))
}

关键技术点

  1. 条件编译:使用 Rust 的 #[cfg] 属性实现平台特定的代码路径。Windows 和 Android 使用 HTTP 协议(http://asset.localhost/),而其他平台使用自定义协议(asset://localhost/)。

  2. 路径规范化:使用 dunce crate 对路径进行 canonicalize 处理,这在 Windows 上尤为重要,因为它能正确处理 UNC 路径和驱动器前缀。

  3. URL 编码:使用 percent-encoding crate 对文件路径进行 URL 编码,确保特殊字符(如空格、中文字符等)在 URL 中能正确传递。

  4. 零依赖添加:巧妙地利用了 Tauri 已有的依赖(duncepercent-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),过程更加熟练:

  1. 探索代码库:使用 gh CLI 搜索相关的 issue,找到了 #12022
  2. 理解需求:阅读 issue 评论,发现维护者已经提供了一个临时的解决方案示例
  3. 本地实现:Fork 仓库,创建新分支 feat/convert-file-src,实现功能
  4. 提交推送:编写清晰的 commit message,推送到 fork 仓库
  5. 创建 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,可以减少维护负担和构建时间。duncepercent-encoding 都是 Tauri 已经使用的依赖,这正是为什么我选择它们的原因。

后续计划

这是一个相对较小的功能增强,PR 创建后等待 Tauri 团队的代码审查。我希望能够通过审查并被合并,为 Tauri 的 Rust 生态系统贡献一份力量。


持续贡献,持续成长。 🚀