Adding ~user tilde recognition in file paths (#5251)

* Added search terms to math commands

* Attempts to add ~user.

From: // Extend this to work with "~user" style of home paths

* Clippy recommendation

* clippy suggestions, again.

* fixing non-compilation on windows and macos

* fmt apparently does not like my imports

* even more clippy issues.

* less expect(), single conversion, match. Should work for MacOS too.

* Attempted to add functionality for windows: all it does is take the home path of current user, and replace the username.

* silly mistake in Windows version of user_home_dir()

* Update tilde.rs

* user_home_dir now returns a path instead of a string - should be smoother with no conversions to string

* clippy warnings

* clippy warnings 2

* Changed user_home_dir to return PathBuf now.

* Changed user_home_dir to return PathBuf now.

* forgot to fmt

* fixed windows build errors from modifying pathbuf but not returning it

* fixed windows clippy errors from returning () instead of pathbuf

* forgot to fmt

* borrowed path did not live long enough.

* previously, path.push did not work because rest_of_path started with "/" - it was not relative. Removing the / makes it a relative path again.

* Issue fixed.

* Update tilde.rs

* fmt.

* There is now a zero chance of panic. All expect()s have been removed.
This commit is contained in:
merelymyself 2022-04-25 06:12:57 +08:00 committed by GitHub
parent 9771270b38
commit b38f90d4c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 154 additions and 1 deletions

45
Cargo.lock generated
View File

@ -988,6 +988,28 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "failure"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
dependencies = [
"backtrace",
"failure_derive",
]
[[package]]
name = "failure_derive"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
dependencies = [
"proc-macro2",
"quote",
"syn",
"synstructure",
]
[[package]] [[package]]
name = "fallible-iterator" name = "fallible-iterator"
version = "0.2.0" version = "0.2.0"
@ -2436,6 +2458,7 @@ version = "0.61.1"
dependencies = [ dependencies = [
"dirs-next", "dirs-next",
"dunce", "dunce",
"pwd",
] ]
[[package]] [[package]]
@ -3282,6 +3305,16 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "pwd"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9ca0304857594109dca88140120427c7a65027be6b77d86a5938588e79cb07b"
dependencies = [
"failure",
"libc",
]
[[package]] [[package]]
name = "quick-error" name = "quick-error"
version = "1.2.3" version = "1.2.3"
@ -4237,6 +4270,18 @@ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]]
name = "synstructure"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
dependencies = [
"proc-macro2",
"quote",
"syn",
"unicode-xid",
]
[[package]] [[package]]
name = "sys-locale" name = "sys-locale"
version = "0.2.0" version = "0.2.0"

View File

@ -9,3 +9,6 @@ version = "0.61.1"
[dependencies] [dependencies]
dirs-next = "2.0.0" dirs-next = "2.0.0"
dunce = "1.0.1" dunce = "1.0.1"
[target.'cfg(target_os = "linux")'.dependencies]
pwd = "1.3.1"

View File

@ -1,10 +1,17 @@
#[cfg(target_os = "linux")]
use pwd::Passwd;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
fn expand_tilde_with_home(path: impl AsRef<Path>, home: Option<PathBuf>) -> PathBuf { fn expand_tilde_with_home(path: impl AsRef<Path>, home: Option<PathBuf>) -> PathBuf {
let path = path.as_ref(); let path = path.as_ref();
if !path.starts_with("~") { if !path.starts_with("~") {
return path.into(); let string = path.to_string_lossy();
let mut path_as_string = string.as_ref().chars();
return match path_as_string.next() {
Some('~') => expand_tilde_with_another_user_home(path),
_ => path.into(),
};
} }
match home { match home {
@ -31,6 +38,104 @@ fn expand_tilde_with_home(path: impl AsRef<Path>, home: Option<PathBuf>) -> Path
} }
} }
#[cfg(target_os = "linux")]
fn user_home_dir(username: &str) -> PathBuf {
let passwd = Passwd::from_name(username);
match &passwd.ok() {
Some(Some(dir)) => PathBuf::from(&dir.dir),
_ => {
let mut file = String::from("/home/");
file.push_str(username);
PathBuf::from(file)
}
}
// PathBuf::from(concat!("/home/", username)),
// Returns home dir of user.
}
#[cfg(target_os = "macos")]
fn user_home_dir(username: &str) -> PathBuf {
match dirs_next::home_dir() {
None => {
let mut expected_path = String::from("/Users/");
expected_path.push_str(username);
let path = Path::new(&expected_path);
let mut home = PathBuf::new();
home.push(path);
home
}
Some(user) => {
let mut expected_path = user;
expected_path.pop();
expected_path.push(Path::new(username));
if expected_path.is_dir() {
expected_path
} else {
let mut expected_path_as_string = String::from("/Users/");
expected_path_as_string.push_str(username);
let path = Path::new(&expected_path_as_string);
let mut home = PathBuf::new();
home.push(path);
home
}
}
}
}
#[cfg(target_os = "windows")]
fn user_home_dir(username: &str) -> PathBuf {
match dirs_next::home_dir() {
None => {
let mut expected_path = String::from("C:\\Users\\");
expected_path.push_str(username);
let path = Path::new(&expected_path);
let mut home = PathBuf::new();
home.push(path);
home
}
Some(user) => {
let mut expected_path = user;
expected_path.pop();
expected_path.push(Path::new(username));
if expected_path.is_dir() {
expected_path
} else {
let mut expected_path_as_string = String::from("C:\\Users\\");
expected_path_as_string.push_str(username);
let path = Path::new(&expected_path_as_string);
let mut home = PathBuf::new();
home.push(path);
home
}
}
}
}
fn expand_tilde_with_another_user_home(path: &Path) -> PathBuf {
return match path.to_str() {
Some(file_path) => {
let mut file = file_path.to_string();
match file_path.chars().position(|c| c == '/' || c == '\\') {
None => {
file.remove(0);
user_home_dir(&file)
}
Some(i) => {
let (pre_name, rest_of_path) = file.split_at(i);
let mut name = pre_name.to_string();
let mut rest_path = rest_of_path.to_string();
rest_path.remove(0);
name.remove(0);
let mut path = user_home_dir(&name);
path.push(Path::new(&rest_path));
path
}
}
}
None => path.to_path_buf(),
};
}
/// Expand tilde ("~") into a home directory if it is the first path component /// Expand tilde ("~") into a home directory if it is the first path component
pub fn expand_tilde(path: impl AsRef<Path>) -> PathBuf { pub fn expand_tilde(path: impl AsRef<Path>) -> PathBuf {
// TODO: Extend this to work with "~user" style of home paths // TODO: Extend this to work with "~user" style of home paths