sweet_utils/path_utils/
path_ext.rs1use super::FsError;
2use super::FsExt;
3use super::FsResult;
4use std::ffi::OsStr;
5use std::path::Path;
6use std::path::PathBuf;
7
8pub struct PathExt;
9
10impl PathExt {
11 pub fn relative(path: &impl AsRef<Path>) -> FsResult<&Path> {
15 let cwd = FsExt::current_dir()?;
16 PathExt::strip_prefix(path, &cwd)
17 }
18
19 pub fn strip_prefix<'a>(
21 path: &'a impl AsRef<Path>,
22 prefix: &impl AsRef<Path>,
23 ) -> FsResult<&'a Path> {
24 path.as_ref()
25 .strip_prefix(prefix)
26 .map_err(|e| FsError::other(path.as_ref(), e))
27 }
28
29 pub fn canonicalize(path: impl AsRef<Path>) -> FsResult<PathBuf> {
32 path.as_ref()
33 .canonicalize()
34 .map_err(|e| FsError::io(path, e))
35 }
36
37 pub fn create_relative(
52 src: impl AsRef<Path>,
53 dst: impl AsRef<Path>,
54 ) -> FsResult<PathBuf> {
55 let path = src.as_ref();
56 let dst = dst.as_ref();
57 pathdiff::diff_paths(dst, path).ok_or_else(|| {
58 FsError::other(
59 path,
60 format!("Could not create relative path to dest: {:?}", dst),
61 )
62 })
63 }
64
65 pub fn to_forward_slash(path: impl AsRef<Path>) -> PathBuf {
66 path.as_ref().to_string_lossy().replace("\\", "/").into()
67 }
68
69 pub fn file_stem(path: &impl AsRef<Path>) -> FsResult<&OsStr> {
70 let path = path.as_ref();
71 path.file_stem()
72 .ok_or_else(|| FsError::other(path, "No file stem"))
73 }
74 pub fn file_name(path: &impl AsRef<Path>) -> FsResult<&OsStr> {
75 let path = path.as_ref();
76 path.file_name()
77 .ok_or_else(|| FsError::other(path, "No file name"))
78 }
79 pub fn is_dir_or_extension(path: &impl AsRef<Path>, ext: &str) -> bool {
80 let path = path.as_ref();
81 match path.extension() {
82 Some(value) => value.to_str().unwrap() == ext,
83 None => path.is_dir(),
84 }
85 }
86}
87
88
89#[cfg(test)]
90mod test {
91 use crate::prelude::*;
92 use std::path::PathBuf;
93
94 #[test]
95 fn works() {
96 assert_eq!(
97 PathExt::create_relative("src", "src/lib.rs").unwrap(),
98 PathBuf::from("lib.rs")
99 );
100 assert_eq!(
101 PathExt::create_relative("foo/bar/src", "foo/bar/Cargo.toml")
102 .unwrap(),
103 PathBuf::from("../Cargo.toml")
104 );
105 }
106}