Skip to main content

simple_unc/
simple_unc.rs

1#[cfg(windows)]
2use crate::Drives;
3use std::{
4    borrow::Cow,
5    fs,
6    path::{Path, PathBuf},
7};
8
9#[derive(Default)]
10pub struct SimpleUnc {}
11
12impl SimpleUnc {
13    pub fn canonicalize(&self, path: impl AsRef<Path>) -> anyhow::Result<PathBuf> {
14        let canonicalized = fs::canonicalize(path)?;
15        #[cfg(windows)]
16        if let Some(simplified) = self.simplify(&canonicalized)? {
17            return Ok(simplified.into_owned());
18        }
19        Ok(canonicalized)
20    }
21
22    pub fn simplify<'a>(&self, path: &'a Path) -> anyhow::Result<Option<Cow<'a, Path>>> {
23        #[cfg(windows)]
24        {
25            // Try mapped network share drives.
26            if let Some(drive_path) = Drives::drive_path(path)? {
27                return Ok(Some(Cow::Owned(drive_path.to_path_buf())));
28            }
29
30            // Try `dunce::simplified`.
31            let simplified = dunce::simplified(path);
32            if !std::ptr::eq(path, simplified) {
33                return Ok(Some(Cow::Borrowed(simplified)));
34            }
35        }
36        Ok(None)
37    }
38
39    /// Refreshes the cached information.
40    pub fn refresh() -> anyhow::Result<()> {
41        #[cfg(windows)]
42        Drives::refresh()
43    }
44}
45
46#[cfg(all(test, windows))]
47mod tests {
48    use super::*;
49
50    #[test]
51    fn simplify_none() {
52        let unc = SimpleUnc::default();
53        assert_eq!(unc.simplify(Path::new(r"C:\foo")).unwrap(), None);
54    }
55
56    #[test]
57    fn simplify_dunce() {
58        let unc = SimpleUnc::default();
59        assert_eq!(
60            unc.simplify(Path::new(r"\\?\C:\foo")).unwrap(),
61            Some(Cow::Borrowed(Path::new(r"C:\foo")))
62        );
63    }
64}