Path 习惯性地在生锈路径中展开瓷砖
有时,例如,在读取某些配置文件时,您读取用户输入的文件路径而不经过shell(例如,您得到Path 习惯性地在生锈路径中展开瓷砖,path,rust,directory,home-directory,Path,Rust,Directory,Home Directory,有时,例如,在读取某些配置文件时,您读取用户输入的文件路径而不经过shell(例如,您得到~/test) 由于下面的选项2没有写入用户主目录中的测试文件,我想知道是否有比选项1更惯用的东西 使用std::env::var; 使用std::fs::File; 使用std::io::prelude::*; 使用std::path::path; fn写入到(路径:&路径){ 让mut f=File::create(path).unwrap(); f、 全部写入(“Hi”。作为字节())。展开(); }
~/test
)
由于下面的选项2
没有写入用户主目录中的测试文件,我想知道是否有比选项1
更惯用的东西
使用std::env::var;
使用std::fs::File;
使用std::io::prelude::*;
使用std::path::path;
fn写入到(路径:&路径){
让mut f=File::create(path).unwrap();
f、 全部写入(“Hi”。作为字节())。展开();
}
fn main(){
//选择1
let from_env=format!(“{}/test”,var(“HOME”).unwrap();
let with_var=Path::new(&from_env);
//创建$HOME/test
写入(带有变量);
//选择2
使用_tilde=Path::new(“~/test”)的let;
//在当前目录中创建测试文件,前提是存在一个目录。/~存在
写入(用波浪号);
}
注意:unwrap()
用于简化示例。生产代码中应该有一些错误处理
shellexpand
(,)似乎可以做您想要做的事情:
extern crate shellexpand; // 1.0.0
#[test]
fn test_shellexpand() {
let home = std::env::var("HOME").unwrap();
assert_eq!(shellexpand::tilde("~/foo"), format!("{}/foo", home));
}
dirs
()进行尝试。这是一张草图:
extern crate dirs; // 1.0.4
use std::path::{Path, PathBuf};
fn expand_tilde<P: AsRef<Path>>(path_user_input: P) -> Option<PathBuf> {
let p = path_user_input.as_ref();
if !p.starts_with("~") {
return Some(p.to_path_buf());
}
if p == Path::new("~") {
return dirs::home_dir();
}
dirs::home_dir().map(|mut h| {
if h == Path::new("/") {
// Corner case: `h` root directory;
// don't prepend extra `/`, just drop the tilde.
p.strip_prefix("~").unwrap().to_path_buf()
} else {
h.push(p.strip_prefix("~/").unwrap());
h
}
})
}
一些评论:
输入类型模仿标准 图书馆有。这就是为什么该方法接受所有的P:AsRef
-like 输入,如Path
,&str
,和&OsStr
&Path
不分配任何内容,它指向 与Path::new
完全相同的字节&str
在这里永远不会失败, 因为我们检查了路径以strip\u前缀(“~/”).unwrap()
和开头 不仅仅是~
。唯一的办法就是 路径以~
开头(因为~/
以
开头) 定义了)
#[test]
fn test_expand_tilde() {
// Should work on your linux box during tests, would fail in stranger
// environments!
let home = std::env::var("HOME").unwrap();
let projects = PathBuf::from(format!("{}/Projects", home));
assert_eq!(expand_tilde("~/Projects"), Some(projects));
assert_eq!(expand_tilde("/foo/bar"), Some("/foo/bar".into()));
assert_eq!(
expand_tilde("~alice/projects"),
Some("~alice/projects".into())
);
}