我认为这应该是非常可行的,因为有一个很好的函数canonicalize
可以规范路径(所以我可以从规范化我的两个输入路径开始)和Path
和PathBuf
给我们一种通过components
迭代路径部分的方法。我想在这里可以解决一些公共前缀,然后在剩余的初始输入路径的锚路径中保留尽可能多的..
组件。
我的问题似乎很常见:
答案 0 :(得分:10)
如果一个路径是另一个路径的基础,您可以使用Path::strip_prefix
,但它不会为您计算../
(而是返回一个Err):
use std::path::*;
let base = Path::new("/foo/bar");
let child_a = Path::new("/foo/bar/a");
let child_b = Path::new("/foo/bar/b");
println!("{:?}", child_a.strip_prefix(base)); // Ok("a")
println!("{:?}", child_a.strip_prefix(child_b)); // Err(StripPrefixError(()))
strip_prefix
的上一个版本是path_relative_from
曾用于添加../
,但是this behavior was dropped due to symlinks:
- 将结果连接到第一个路径上的当前行为明确地指的是第二个路径所做的相同的事情,即使有符号链接(基本上意味着
base
需要是{{}的前缀1}})- 结果可以从
self
组件开始的旧行为。符号链接意味着遍历../
路径,然后遍历返回的相对路径可能不会将您放在遍历base
路径的同一目录中。但是,如果您正在使用不关心符号链接的基于路径的系统,或者您已经在您正在使用的路径中解决了符号链接,则此操作非常有用。< / LI> 醇>
如果您需要self
行为,则可以从librustc_back(编译器后端)复制实现。我还没有在crates.io上找到任何包裹。
../
答案 1 :(得分:5)
现在使用pathdiff
您可以将其用作:
extern crate pathdiff;
pathdiff::diff_paths(path, base);
其中base
是应用相对路径以获取path