Blazing-fast Rust absolute long path refactoring and use injection tool, purpose-built to automatically resolve clippy::absolute_paths warnings. Can be used both as a standalone CLI / Cargo plugin, and embedded directly as a Rust library crate.
Before refactoring:
// Original code: littered with redundant, qualified absolute paths
fn handle_data() -> Result<(), std::io::Error> {
let now = std::time::Instant::now();
let data = wbase::time::now_secs();
let code = std::io::ErrorKind::NotFound;
Ok(())
}
After running fixrs (automatically injects use statements at the top, simplifies call-sites, and runs rustfmt):
use std::io::{Error, ErrorKind};
use std::time::Instant;
use wbase::time::now_secs;
fn handle_data() -> Result<(), Error> {
let now = Instant::now();
let data = now_secs();
let code = ErrorKind::NotFound;
Ok(())
}
# Install
cargo install fixrs
# Run in any Rust project root (in-place rewrite + auto rustfmt)
fixrs
# Or as a cargo plugin
cargo fixrs
# Dry-run mode (preview without modifying files)
fixrs -n
Clippy's clippy::absolute_paths restriction lint flags long qualified paths in favor of clean, readable imports. However, cargo clippy --fix explicitly does not support auto-fixing this lint (see official implementation clippy_lints/src/absolute_paths.rs, which only issues warnings and lacks MachineApplicable automated suggestions).
Here is why:
use declarations at the file header and shortening paths inside functions. When multiple replacements occur in the same file, cargo fix aborts due to overlapping replacements.std::io::Error is blindly shortened to Error with use std::io::Error;, but the file already declares an enum Error or a local variable let Error = ..., fatal compilation errors occur.std::fmt::Debug or std::fmt::Display is imported directly into scope, calling .fmt(f) on objects implementing multiple format traits fails with compiler error E0034.#![no_implicit_prelude]: Extracting a path from a #[cfg(feature = "...")] block into an unconditional top-level use breaks no_std or cross-platform builds. Replacing paths inside macro_rules! can corrupt macro expansion.std::collections::HashMap::new(), tokio::sync::mpsc::channel(), std::sync::atomic::AtomicBool::new()) to avoid missing imports;use imports, code density improves dramatically, reducing token usage across multi-turn chats, automated refactoring, and AI code reviews while speeding up model inference.fixrs addresses every single one of these challenges:
io::Error with use std::io;);(core|std)::fmt: preserves the fmt:: prefix to prevent Trait method ambiguity;#[cfg] blocks, macro_rules! definitions, and #![no_implicit_prelude] environments;rustfmt formatting.In collaborative team environments, the default .git/hooks/ directory is local-only and not tracked by Git, making manual hook setup error-prone for new contributors.
The recommended best practice is to use Git's native core.hooksPath tracked directory mechanism (zero third-party dependencies, version-controlled, synced automatically across all team members):
Create a version-controlled .githooks directory at the project root and add the pre-commit hook:
mkdir -p .githooks
cat << 'EOF' > .githooks/pre-commit
#!/bin/sh
set -e
# Automatically simplify qualified paths and format before commit
echo "[git-hook] Running fixrs to optimize imports..."
fixrs
# Stage the cleaned and formatted files
git add -u
EOF
chmod +x .githooks/pre-commit
git add .githooks/pre-commit
When team members clone the repository, they simply point Git's hook path to the tracked directory:
git config core.hooksPath .githooks
You can also embed this one-liner into your project's setup script, Makefile, or Justfile. Future updates to the hook are tracked in Git and propagate to everyone seamlessly on git pull.
fixrs is not just a command-line utility. Its entire engine is cleanly encapsulated as a high-cohesion, lightweight Rust library that can be integrated into code generators, macros, language servers, or automated refactoring pipelines.
Add fixrs to your Cargo.toml:
[dependencies]
fixrs = "0.1"
fix_str)use fixrs::{Options, fix_str};
fn main() -> fixrs::Result<()> {
let source = r#"
fn run() -> Result<(), std::io::Error> {
let now = std::time::Instant::now();
Ok(())
}
"#;
let options = Options::new().max_segments(2);
if let Some(fixed_code) = fix_str(source, &options)? {
println!("{fixed_code}");
}
Ok(())
}
fix_source)use fixrs::{Options, fix_source};
let code = "fn test() { let _ = std::time::Instant::now(); }";
let options = Options::new().max_segments(2);
if let Some(result) = fix_source(code, &options)? {
println!("Rewritten source:\n{}", result.content);
for (original, replacement) in result.replacements {
println!("Replacement: {original} -> {replacement}");
}
}
fix_file / fix_project)use std::path::Path;
use fixrs::{Options, fix_file, fix_project};
// Process a single file (automatically discovers project root Cargo.toml)
let file_result = fix_file(Path::new("src/main.rs"), &Options::default())?;
// Batch process an entire project directory
let summary = fix_project(&Options::new().path("."))?;
println!("Completed: changed {} files with {} replacements", summary.changed_files, summary.total_replacements);
# 1. Default: scan current Cargo workspace, rewrite in place, and format
fixrs
# 2. Specify target path: process a directory or file
fixrs src/
fixrs src/main.rs
# 3. Dry-run mode: preview changes without writing to disk
fixrs -n
# 4. CI check mode: exit with code 1 if long paths exist
fixrs -c
# 5. Quiet mode: suppress detailed replacement output
fixrs -q
| Option | Default | Description |
|---|---|---|
[PATH] | Nearest Cargo.toml root | Target directory or .rs file to process |
-n, --dry-run | false | Dry-run preview mode; do not modify files |
-c, --check | false | CI check mode; exit code 1 if unallowed paths exist |
-s, --show | false | Force printing file paths and replacement details |
-q, --quiet | false | Quiet mode; suppress detailed outputs |
-m, --max-segments <N> | 2 | Maximum allowed path segments (matching Clippy default) |
-k, --keep-segments <N> | 1 | Number of segments to keep in code (default: last 1 segment) |
-a, --allow-crate <NAME> | None | Crates allowed to keep qualified paths (e.g. -a std -a core) |
--crate <NAME> | None | Extra external crate names to recognize |
--no-cache | false | Disable incremental cache and force a full re-scan |
--verbose | false | Enable verbose logging output |
syn AST traversal. No rustc compiler invocation, no heavy metadata loading—single files are parsed in milliseconds.compio runtime, dispatching work per CPU core for maximum throughput across massive codebases in hundreds of milliseconds.museair nanosecond hashing and project metadata caching. Unmodified files skip instantaneously; cache invalidates automatically when options change.Cargo.toml and workspace dependencies/dev-dependencies to distinguish local modules from external crates.ignore, honoring .gitignore rules and skipping target/, node_modules/, and hidden folders.tokio, serde, regex, tower, clap, rustix, mio, socket2, rand, tempfile, thiserror, tar, backtrace, and more—passing 100% of official test suites after refactoring!极速 Rust 绝对长路径自动重构与 use 导入注入工具,专为全自动修复 clippy::absolute_paths 警告而生。既可作为独立命令行工具或 Cargo 插件,也可直接作为 Rust 库嵌入程序中使用。
重构前代码:
// 原始代码:充斥冗长的跨模块、跨 crate 绝对路径
fn handle_data() -> Result<(), std::io::Error> {
let now = std::time::Instant::now();
let data = wbase::time::now_secs();
let code = std::io::ErrorKind::NotFound;
Ok(())
}
运行 fixrs 重构后(全自动在顶层注入 use 并简化,保留排版与注释):
use std::io::{Error, ErrorKind};
use std::time::Instant;
use wbase::time::now_secs;
fn handle_data() -> Result<(), Error> {
let now = Instant::now();
let data = now_secs();
let code = ErrorKind::NotFound;
Ok(())
}
# 安装
cargo install fixrs
# 进入任意 Rust 项目目录,一键扫描、就地重构并自动调用 rustfmt 格式化
fixrs
# 或作为 cargo 子命令运行
cargo fixrs
# 试运行预览(仅在终端输出待替换明细,不改写文件)
fixrs -n
Clippy 的 clippy::absolute_paths 检查规则会严格限制代码中的绝对长路径,倡导提升代码可读性。然而,Rust 官方的 cargo clippy --fix 明确不支持该规则的自动修复(见官方实现 clippy_lints/src/absolute_paths.rs,仅发出警告而未提供任何可机读自动修复)。
痛点原因如下:
use 声明,并在函数或结构体内部替换标识符。同一文件中多处长路径替换极易导致补丁重叠冲突,官方工具直接放弃修复。std::io::Error 简化为 Error 并引入 use std::io::Error;,一旦当前文件已有自定义 enum Error 或函数局部变量 let Error = ...,就会引发编译报错。std::fmt::Debug 裸导入,任何同时实现了 Debug 和 Display 的对象在调用 .fmt(f) 时,将因方法多义性而导致编译失败。#[cfg(feature = "...")] 的代码块中若将路径提取为顶层无条件 use,会导致跨平台构建或 no_std 环境被破坏;在宏定义 macro_rules! 中盲目替换更会导致宏展开失效。std::sync::atomic::AtomicBool::new()、tokio::sync::mpsc::channel()、std::collections::HashMap::new() 等);fixrs 彻底解决了上述全部痛点:
io::Error 并引入 use std::io;);(core|std)::fmt 统一强制保留 fmt:: 前缀并仅导入模块,从源头杜绝特征方法多义性;#[cfg] 条件编译块与 macro_rules! 宏定义;#![no_implicit_prelude] 并实施安全保护;rustfmt 完成优雅排版。在多人协作团队中,默认的 .git/hooks/ 属于本地私有目录,不会被 Git 版本库跟踪,新成员拉取代码后常常遗漏配置。
推荐采用 Git 原生支持的 core.hooksPath 版本受控目录方案(零第三方工具依赖,一人配置,全员自动同步):
在项目根目录下创建受版本控制的 .githooks 目录,并添加 pre-commit 脚本:
mkdir -p .githooks
cat << 'EOF' > .githooks/pre-commit
#!/bin/sh
set -e
# 提交前全自动运行 fixrs 简化长绝对路径并格式化
echo "[git-hook] 正在运行 fixrs 优化路径..."
fixrs
# 将被自动修复的文件重新加入暂存区
git add -u
EOF
chmod +x .githooks/pre-commit
git add .githooks/pre-commit
团队新成员克隆仓库后,只需在项目根目录运行一行配置,将仓库钩子路径指向受控目录:
git config core.hooksPath .githooks
亦可将此命令加入项目的初始化脚本、构建脚本(如 Makefile、Justfile)或安装文档中。后续提交钩子的任何规则迭代与更新都会随 git pull 自动同步给全体成员,在每次 git commit 时全自动执行长路径清理与规范排版。
fixrs 核心解析与改写引擎完全封装为高内聚、轻量级的 Rust 原生库,可轻松集成至代码生成器、过程宏测试、静态分析平台或工程重构工具链中。
在 Cargo.toml 中添加依赖:
[dependencies]
fixrs = "0.1"
fix_str)use fixrs::{Options, fix_str};
fn main() -> fixrs::Result<()> {
let source = r#"
fn run() -> Result<(), std::io::Error> {
let now = std::time::Instant::now();
Ok(())
}
"#;
let options = Options::new().max_segments(2);
if let Some(fixed_code) = fix_str(source, &options)? {
println!("{fixed_code}");
}
Ok(())
}
fix_source)use fixrs::{Options, fix_source};
let code = "fn test() { let _ = std::time::Instant::now(); }";
let options = Options::new().max_segments(2);
if let Some(result) = fix_source(code, &options)? {
println!("改写后的源码:\n{}", result.content);
for (original, replacement) in result.replacements {
println!("替换项: {original} -> {replacement}");
}
}
fix_file / fix_project)use std::path::Path;
use fixrs::{Options, fix_file, fix_project};
// 处理单个源文件(自动识别最近的 Cargo.toml 解析依赖关系)
let file_result = fix_file(Path::new("src/main.rs"), &Options::default())?;
// 批量扫描并就地处理整个项目
let summary = fix_project(&Options::new().path("."))?;
println!("处理完成:成功改写 {} 个文件,共 {} 处替换", summary.changed_files, summary.total_replacements);
# 1. 默认执行:递归扫描当前 Cargo 项目所有源文件,就地修改并格式化
fixrs
# 2. 指定路径:处理特定目录或单文件
fixrs src/
fixrs src/main.rs
# 3. 试运行模式:仅在终端输出待替换明细,不改写文件
fixrs -n
# 4. CI 检查模式:发现未简化长路径时返回退出码 1
fixrs -c
# 5. 静默模式:不输出任何细节
fixrs -q
| 参数 | 默认值 | 说明 |
|---|---|---|
[PATH] | 自动向上检索的 Cargo.toml 根目录 | 待处理的目标目录或单个 .rs 文件 |
-n, --dry-run | false | 试运行预览模式,不实际写回文件 |
-c, --check | false | 检查模式,存在待简化路径时退出码为 1 |
-s, --show | false | 强制在终端打印每个文件的详细替换明细 |
-q, --quiet | false | 静默模式,压制明细输出 |
-m, --max-segments <N> | 2 | 允许的最大绝对路径段数(与 Clippy 默认一致) |
-k, --keep-segments <N> | 1 | 替换后代码中保留的段数(默认保留末尾 1 段) |
-a, --allow-crate <NAME> | 无 | 允许保留绝对长路径的 crate 白名单(如 -a std -a core) |
--crate <NAME> | 无 | 额外指定的已知外部 crate 名称 |
--no-cache | false | 禁用增量缓存,强制重新解析全部文件 |
--verbose | false | 输出详细处理日志 |
syn 抽象语法树遍历,无需调用 rustc 或加载庞大元数据,单文件毫秒级完成。compio 运行时调度,一个 CPU 核心绑定一个独立工作线程,超大工程数百毫秒极速完成。museair 纳秒级哈希与项目元数据缓存,跳过未修改文件;规则变更时缓存自动失效。Cargo.toml 及工作区直接依赖与开发依赖,避免将项目内部模块误判为外部 crate。ignore 库,严格遵循 .gitignore,自动跳过 target/、node_modules/、隐藏目录及构建输出。tokio、serde、regex、tower、clap、rustix、mio、socket2、rand、tempfile、thiserror、tar、backtrace 等)的真实代码库中实测验证,所有修改通过全部官方单元测试与回归测试!1 commits
Rust
99.5%
Blazing-fast Rust absolute long path refactoring and use injection tool, purpose-built to automatically resolve clippy::absolute_paths warnings. Can be used both as a standalone CLI / Cargo plugin, and embedded directly as a Rust library crate.
Before refactoring:
// Original code: littered with redundant, qualified absolute paths
fn handle_data() -> Result<(), std::io::Error> {
let now = std::time::Instant::now();
let data = wbase::time::now_secs();
let code = std::io::ErrorKind::NotFound;
Ok(())
}
After running fixrs (automatically injects use statements at the top, simplifies call-sites, and runs rustfmt):
use std::io::{Error, ErrorKind};
use std::time::Instant;
use wbase::time::now_secs;
fn handle_data() -> Result<(), Error> {
let now = Instant::now();
let data = now_secs();
let code = ErrorKind::NotFound;
Ok(())
}
# Install
cargo install fixrs
# Run in any Rust project root (in-place rewrite + auto rustfmt)
fixrs
# Or as a cargo plugin
cargo fixrs
# Dry-run mode (preview without modifying files)
fixrs -n
Clippy's clippy::absolute_paths restriction lint flags long qualified paths in favor of clean, readable imports. However, cargo clippy --fix explicitly does not support auto-fixing this lint (see official implementation clippy_lints/src/absolute_paths.rs, which only issues warnings and lacks MachineApplicable automated suggestions).
Here is why:
use declarations at the file header and shortening paths inside functions. When multiple replacements occur in the same file, cargo fix aborts due to overlapping replacements.std::io::Error is blindly shortened to Error with use std::io::Error;, but the file already declares an enum Error or a local variable let Error = ..., fatal compilation errors occur.std::fmt::Debug or std::fmt::Display is imported directly into scope, calling .fmt(f) on objects implementing multiple format traits fails with compiler error E0034.#![no_implicit_prelude]: Extracting a path from a #[cfg(feature = "...")] block into an unconditional top-level use breaks no_std or cross-platform builds. Replacing paths inside macro_rules! can corrupt macro expansion.std::collections::HashMap::new(), tokio::sync::mpsc::channel(), std::sync::atomic::AtomicBool::new()) to avoid missing imports;use imports, code density improves dramatically, reducing token usage across multi-turn chats, automated refactoring, and AI code reviews while speeding up model inference.fixrs addresses every single one of these challenges:
io::Error with use std::io;);(core|std)::fmt: preserves the fmt:: prefix to prevent Trait method ambiguity;#[cfg] blocks, macro_rules! definitions, and #![no_implicit_prelude] environments;rustfmt formatting.In collaborative team environments, the default .git/hooks/ directory is local-only and not tracked by Git, making manual hook setup error-prone for new contributors.
The recommended best practice is to use Git's native core.hooksPath tracked directory mechanism (zero third-party dependencies, version-controlled, synced automatically across all team members):
Create a version-controlled .githooks directory at the project root and add the pre-commit hook:
mkdir -p .githooks
cat << 'EOF' > .githooks/pre-commit
#!/bin/sh
set -e
# Automatically simplify qualified paths and format before commit
echo "[git-hook] Running fixrs to optimize imports..."
fixrs
# Stage the cleaned and formatted files
git add -u
EOF
chmod +x .githooks/pre-commit
git add .githooks/pre-commit
When team members clone the repository, they simply point Git's hook path to the tracked directory:
git config core.hooksPath .githooks
You can also embed this one-liner into your project's setup script, Makefile, or Justfile. Future updates to the hook are tracked in Git and propagate to everyone seamlessly on git pull.
fixrs is not just a command-line utility. Its entire engine is cleanly encapsulated as a high-cohesion, lightweight Rust library that can be integrated into code generators, macros, language servers, or automated refactoring pipelines.
Add fixrs to your Cargo.toml:
[dependencies]
fixrs = "0.1"
fix_str)use fixrs::{Options, fix_str};
fn main() -> fixrs::Result<()> {
let source = r#"
fn run() -> Result<(), std::io::Error> {
let now = std::time::Instant::now();
Ok(())
}
"#;
let options = Options::new().max_segments(2);
if let Some(fixed_code) = fix_str(source, &options)? {
println!("{fixed_code}");
}
Ok(())
}
fix_source)use fixrs::{Options, fix_source};
let code = "fn test() { let _ = std::time::Instant::now(); }";
let options = Options::new().max_segments(2);
if let Some(result) = fix_source(code, &options)? {
println!("Rewritten source:\n{}", result.content);
for (original, replacement) in result.replacements {
println!("Replacement: {original} -> {replacement}");
}
}
fix_file / fix_project)use std::path::Path;
use fixrs::{Options, fix_file, fix_project};
// Process a single file (automatically discovers project root Cargo.toml)
let file_result = fix_file(Path::new("src/main.rs"), &Options::default())?;
// Batch process an entire project directory
let summary = fix_project(&Options::new().path("."))?;
println!("Completed: changed {} files with {} replacements", summary.changed_files, summary.total_replacements);
# 1. Default: scan current Cargo workspace, rewrite in place, and format
fixrs
# 2. Specify target path: process a directory or file
fixrs src/
fixrs src/main.rs
# 3. Dry-run mode: preview changes without writing to disk
fixrs -n
# 4. CI check mode: exit with code 1 if long paths exist
fixrs -c
# 5. Quiet mode: suppress detailed replacement output
fixrs -q
| Option | Default | Description |
|---|---|---|
[PATH] | Nearest Cargo.toml root | Target directory or .rs file to process |
-n, --dry-run | false | Dry-run preview mode; do not modify files |
-c, --check | false | CI check mode; exit code 1 if unallowed paths exist |
-s, --show | false | Force printing file paths and replacement details |
-q, --quiet | false | Quiet mode; suppress detailed outputs |
-m, --max-segments <N> | 2 | Maximum allowed path segments (matching Clippy default) |
-k, --keep-segments <N> | 1 | Number of segments to keep in code (default: last 1 segment) |
-a, --allow-crate <NAME> | None | Crates allowed to keep qualified paths (e.g. -a std -a core) |
--crate <NAME> | None | Extra external crate names to recognize |
--no-cache | false | Disable incremental cache and force a full re-scan |
--verbose | false | Enable verbose logging output |
syn AST traversal. No rustc compiler invocation, no heavy metadata loading—single files are parsed in milliseconds.compio runtime, dispatching work per CPU core for maximum throughput across massive codebases in hundreds of milliseconds.museair nanosecond hashing and project metadata caching. Unmodified files skip instantaneously; cache invalidates automatically when options change.Cargo.toml and workspace dependencies/dev-dependencies to distinguish local modules from external crates.ignore, honoring .gitignore rules and skipping target/, node_modules/, and hidden folders.tokio, serde, regex, tower, clap, rustix, mio, socket2, rand, tempfile, thiserror, tar, backtrace, and more—passing 100% of official test suites after refactoring!极速 Rust 绝对长路径自动重构与 use 导入注入工具,专为全自动修复 clippy::absolute_paths 警告而生。既可作为独立命令行工具或 Cargo 插件,也可直接作为 Rust 库嵌入程序中使用。
重构前代码:
// 原始代码:充斥冗长的跨模块、跨 crate 绝对路径
fn handle_data() -> Result<(), std::io::Error> {
let now = std::time::Instant::now();
let data = wbase::time::now_secs();
let code = std::io::ErrorKind::NotFound;
Ok(())
}
运行 fixrs 重构后(全自动在顶层注入 use 并简化,保留排版与注释):
use std::io::{Error, ErrorKind};
use std::time::Instant;
use wbase::time::now_secs;
fn handle_data() -> Result<(), Error> {
let now = Instant::now();
let data = now_secs();
let code = ErrorKind::NotFound;
Ok(())
}
# 安装
cargo install fixrs
# 进入任意 Rust 项目目录,一键扫描、就地重构并自动调用 rustfmt 格式化
fixrs
# 或作为 cargo 子命令运行
cargo fixrs
# 试运行预览(仅在终端输出待替换明细,不改写文件)
fixrs -n
Clippy 的 clippy::absolute_paths 检查规则会严格限制代码中的绝对长路径,倡导提升代码可读性。然而,Rust 官方的 cargo clippy --fix 明确不支持该规则的自动修复(见官方实现 clippy_lints/src/absolute_paths.rs,仅发出警告而未提供任何可机读自动修复)。
痛点原因如下:
use 声明,并在函数或结构体内部替换标识符。同一文件中多处长路径替换极易导致补丁重叠冲突,官方工具直接放弃修复。std::io::Error 简化为 Error 并引入 use std::io::Error;,一旦当前文件已有自定义 enum Error 或函数局部变量 let Error = ...,就会引发编译报错。std::fmt::Debug 裸导入,任何同时实现了 Debug 和 Display 的对象在调用 .fmt(f) 时,将因方法多义性而导致编译失败。#[cfg(feature = "...")] 的代码块中若将路径提取为顶层无条件 use,会导致跨平台构建或 no_std 环境被破坏;在宏定义 macro_rules! 中盲目替换更会导致宏展开失效。std::sync::atomic::AtomicBool::new()、tokio::sync::mpsc::channel()、std::collections::HashMap::new() 等);fixrs 彻底解决了上述全部痛点:
io::Error 并引入 use std::io;);(core|std)::fmt 统一强制保留 fmt:: 前缀并仅导入模块,从源头杜绝特征方法多义性;#[cfg] 条件编译块与 macro_rules! 宏定义;#![no_implicit_prelude] 并实施安全保护;rustfmt 完成优雅排版。在多人协作团队中,默认的 .git/hooks/ 属于本地私有目录,不会被 Git 版本库跟踪,新成员拉取代码后常常遗漏配置。
推荐采用 Git 原生支持的 core.hooksPath 版本受控目录方案(零第三方工具依赖,一人配置,全员自动同步):
在项目根目录下创建受版本控制的 .githooks 目录,并添加 pre-commit 脚本:
mkdir -p .githooks
cat << 'EOF' > .githooks/pre-commit
#!/bin/sh
set -e
# 提交前全自动运行 fixrs 简化长绝对路径并格式化
echo "[git-hook] 正在运行 fixrs 优化路径..."
fixrs
# 将被自动修复的文件重新加入暂存区
git add -u
EOF
chmod +x .githooks/pre-commit
git add .githooks/pre-commit
团队新成员克隆仓库后,只需在项目根目录运行一行配置,将仓库钩子路径指向受控目录:
git config core.hooksPath .githooks
亦可将此命令加入项目的初始化脚本、构建脚本(如 Makefile、Justfile)或安装文档中。后续提交钩子的任何规则迭代与更新都会随 git pull 自动同步给全体成员,在每次 git commit 时全自动执行长路径清理与规范排版。
fixrs 核心解析与改写引擎完全封装为高内聚、轻量级的 Rust 原生库,可轻松集成至代码生成器、过程宏测试、静态分析平台或工程重构工具链中。
在 Cargo.toml 中添加依赖:
[dependencies]
fixrs = "0.1"
fix_str)use fixrs::{Options, fix_str};
fn main() -> fixrs::Result<()> {
let source = r#"
fn run() -> Result<(), std::io::Error> {
let now = std::time::Instant::now();
Ok(())
}
"#;
let options = Options::new().max_segments(2);
if let Some(fixed_code) = fix_str(source, &options)? {
println!("{fixed_code}");
}
Ok(())
}
fix_source)use fixrs::{Options, fix_source};
let code = "fn test() { let _ = std::time::Instant::now(); }";
let options = Options::new().max_segments(2);
if let Some(result) = fix_source(code, &options)? {
println!("改写后的源码:\n{}", result.content);
for (original, replacement) in result.replacements {
println!("替换项: {original} -> {replacement}");
}
}
fix_file / fix_project)use std::path::Path;
use fixrs::{Options, fix_file, fix_project};
// 处理单个源文件(自动识别最近的 Cargo.toml 解析依赖关系)
let file_result = fix_file(Path::new("src/main.rs"), &Options::default())?;
// 批量扫描并就地处理整个项目
let summary = fix_project(&Options::new().path("."))?;
println!("处理完成:成功改写 {} 个文件,共 {} 处替换", summary.changed_files, summary.total_replacements);
# 1. 默认执行:递归扫描当前 Cargo 项目所有源文件,就地修改并格式化
fixrs
# 2. 指定路径:处理特定目录或单文件
fixrs src/
fixrs src/main.rs
# 3. 试运行模式:仅在终端输出待替换明细,不改写文件
fixrs -n
# 4. CI 检查模式:发现未简化长路径时返回退出码 1
fixrs -c
# 5. 静默模式:不输出任何细节
fixrs -q
| 参数 | 默认值 | 说明 |
|---|---|---|
[PATH] | 自动向上检索的 Cargo.toml 根目录 | 待处理的目标目录或单个 .rs 文件 |
-n, --dry-run | false | 试运行预览模式,不实际写回文件 |
-c, --check | false | 检查模式,存在待简化路径时退出码为 1 |
-s, --show | false | 强制在终端打印每个文件的详细替换明细 |
-q, --quiet | false | 静默模式,压制明细输出 |
-m, --max-segments <N> | 2 | 允许的最大绝对路径段数(与 Clippy 默认一致) |
-k, --keep-segments <N> | 1 | 替换后代码中保留的段数(默认保留末尾 1 段) |
-a, --allow-crate <NAME> | 无 | 允许保留绝对长路径的 crate 白名单(如 -a std -a core) |
--crate <NAME> | 无 | 额外指定的已知外部 crate 名称 |
--no-cache | false | 禁用增量缓存,强制重新解析全部文件 |
--verbose | false | 输出详细处理日志 |
syn 抽象语法树遍历,无需调用 rustc 或加载庞大元数据,单文件毫秒级完成。compio 运行时调度,一个 CPU 核心绑定一个独立工作线程,超大工程数百毫秒极速完成。museair 纳秒级哈希与项目元数据缓存,跳过未修改文件;规则变更时缓存自动失效。Cargo.toml 及工作区直接依赖与开发依赖,避免将项目内部模块误判为外部 crate。ignore 库,严格遵循 .gitignore,自动跳过 target/、node_modules/、隐藏目录及构建输出。tokio、serde、regex、tower、clap、rustix、mio、socket2、rand、tempfile、thiserror、tar、backtrace 等)的真实代码库中实测验证,所有修改通过全部官方单元测试与回归测试!1 commits
Rust
99.5%