Skip to main content

simple_unc/
simple_unc.rs

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