Skip to main content

lexe_std/
path.rs

1use std::path::{Path, PathBuf};
2
3pub trait PathExt {
4    /// Return a new `PathBuf` with all existing extensions removed and
5    /// replaced with `new_ext`.
6    ///
7    /// ex: "foo.tar.gz" with `new_ext="zip"` becomes "foo.zip"
8    fn with_all_extensions(&self, new_ext: &str) -> PathBuf;
9}
10
11impl PathExt for Path {
12    fn with_all_extensions(&self, new_ext: &str) -> PathBuf {
13        let mut path = self.to_path_buf();
14        while path.extension().is_some() {
15            path.set_extension("");
16        }
17        path.set_extension(new_ext);
18        path
19    }
20}
21
22#[cfg(test)]
23mod test {
24    use std::path::Path;
25
26    use super::PathExt;
27
28    #[test]
29    fn test_with_all_extensions() {
30        let cases = [
31            ("foo.txt", "md", "foo.md"),
32            ("foo.tar.gz", "zip", "foo.zip"),
33            ("foo", "txt", "foo.txt"),
34            (".hiddenfile", "txt", ".hiddenfile.txt"),
35            ("archive.backup.tar.gz", "7z", "archive.7z"),
36        ];
37
38        for (input, new_ext, expected) in cases {
39            let input_path = Path::new(input);
40            let result = input_path.with_all_extensions(new_ext);
41            assert_eq!(result, Path::new(expected));
42        }
43    }
44}