normalize_punctuation/
utils.rs1use std::borrow::Cow;
4use std::env;
5use std::fs::File;
6use std::io::{self, Read};
7use std::path::{Path, PathBuf};
8use std::sync::OnceLock;
9
10use pathdiff;
11
12#[must_use]
24pub fn path_relative_to_cwd(path: &Path) -> Cow<Path> {
25 static CWD: OnceLock<Option<PathBuf>> = OnceLock::new();
28 let Some(base_dir) = CWD.get_or_init(|| {
29 #[cfg(test)]
30 {
31 return Some(PathBuf::from(env!("CARGO_MANIFEST_DIR")));
32 }
33 #[allow(unreachable_code)]
34 env::current_dir().ok()
35 }) else {
36 #[cfg(not(tarpaulin_include))]
38 return Cow::Borrowed(path);
39 };
40
41 if let Some(diffed) = pathdiff::diff_paths(path, base_dir) {
42 if diffed == Path::new("") {
43 Cow::Borrowed(path)
44 } else {
45 Cow::Owned(diffed)
46 }
47 } else {
48 Cow::Borrowed(path)
49 }
50}
51
52pub fn read_to_string_buffer(buffer: &mut String, path: &Path) -> io::Result<usize> {
62 let mut file = File::open(path)?;
63 buffer.clear();
64 file.read_to_string(buffer)
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 const CWD: &str = env!("CARGO_MANIFEST_DIR");
72
73 #[test]
74 fn path_relative_to_cwd_regular() {
75 let file = Path::new(CWD).join("foo/bar.txt");
76
77 assert_eq!(path_relative_to_cwd(&file), Path::new("foo/bar.txt"));
78 }
79
80 #[test]
81 fn path_relative_to_cwd_equal() {
82 let file = Path::new(CWD);
83
84 assert_eq!(path_relative_to_cwd(file), file);
85 }
86
87 #[test]
88 fn path_relative_to_cwd_parent() {
89 let file = Path::new(CWD).parent().unwrap().join("foo/bar.txt");
90
91 assert_eq!(path_relative_to_cwd(&file), Path::new("../foo/bar.txt"));
92 }
93
94 #[test]
95 fn path_relative_to_cwd_relative_path() {
96 let file = Path::new("foo/bar.txt");
97
98 assert_eq!(path_relative_to_cwd(file), file);
100 }
101}