1#![cfg_attr(not(target_os = "windows"), allow(unused))]
2#[cfg(windows)]
3use crate::{Drives, PathExt};
4use std::{
5 borrow::Cow,
6 fs,
7 path::{Path, PathBuf},
8};
9
10#[derive(Default)]
11pub struct SimpleUnc {
12 pub map_to_drive: bool,
23}
24
25impl SimpleUnc {
26 pub fn canonicalize(&self, path: impl AsRef<Path>) -> anyhow::Result<PathBuf> {
27 let canonicalized = fs::canonicalize(path)?;
28 #[cfg(windows)]
29 if let Some(simplified) = self.simplify(&canonicalized)? {
30 return Ok(simplified.into_owned());
31 }
32 Ok(canonicalized)
33 }
34
35 pub fn simplify<'a>(&self, path: &'a Path) -> anyhow::Result<Option<Cow<'a, Path>>> {
36 #[cfg(windows)]
37 {
38 if let Some(drive_path) = Drives::drive_path(path)? {
40 if self.map_to_drive {
41 return Ok(Some(Cow::Owned(drive_path.to_path_buf())));
42 }
43 if let Some(stripped) = path.strip_win32_file_namespace_unc() {
44 return Ok(Some(Cow::Owned(stripped)));
45 }
46 }
47
48 let simplified = dunce::simplified(path);
50 if !std::ptr::eq(path, simplified) {
51 return Ok(Some(Cow::Borrowed(simplified)));
52 }
53 }
54 Ok(None)
55 }
56
57 pub fn refresh() -> anyhow::Result<()> {
59 #[cfg(windows)]
60 Drives::refresh()?;
61 Ok(())
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn simplify_none() {
71 let unc = SimpleUnc::default();
72 assert_eq!(unc.simplify(Path::new(r"C:\foo")).unwrap(), None);
73 }
74
75 #[cfg(windows)]
76 #[test]
77 fn simplify_dunce() {
78 let unc = SimpleUnc::default();
79 assert_eq!(
80 unc.simplify(Path::new(r"\\?\C:\foo")).unwrap(),
81 Some(Cow::Borrowed(Path::new(r"C:\foo")))
82 );
83 }
84}