1use std::path::Path;
2#[cfg(windows)]
3use std::path::{Component, Prefix};
4
5use crate::AbsolutePathBuf;
6
7pub fn home_dir() -> Option<AbsolutePathBuf> {
8 dirs::home_dir().and_then(|home| AbsolutePathBuf::try_from(home).ok())
9}
10
11#[cfg(windows)]
20pub fn is_windows_device_path(path: &Path) -> bool {
21 match path.components().next() {
22 Some(Component::Prefix(prefix)) if matches!(prefix.kind(), Prefix::DeviceNS(_)) => {
23 return true;
24 }
25 _ => {}
26 }
27 let special_paths: [&Path; 28] = [
28 Path::new("CON"),
29 Path::new("PRN"),
30 Path::new("AUX"),
31 Path::new("NUL"),
32 Path::new("COM1"),
33 Path::new("COM2"),
34 Path::new("COM3"),
35 Path::new("COM4"),
36 Path::new("COM5"),
37 Path::new("COM6"),
38 Path::new("COM7"),
39 Path::new("COM8"),
40 Path::new("COM9"),
41 Path::new("COM¹"),
42 Path::new("COM²"),
43 Path::new("COM³"),
44 Path::new("LPT1"),
45 Path::new("LPT2"),
46 Path::new("LPT3"),
47 Path::new("LPT4"),
48 Path::new("LPT5"),
49 Path::new("LPT6"),
50 Path::new("LPT7"),
51 Path::new("LPT8"),
52 Path::new("LPT9"),
53 Path::new("LPT¹"),
54 Path::new("LPT²"),
55 Path::new("LPT³"),
56 ];
57 if special_paths.contains(&path) {
58 return true;
59 }
60 false
61}
62
63#[cfg(not(windows))]
64pub fn is_windows_device_path(_path: &Path) -> bool {
65 false
66}
67
68#[cfg(test)]
69mod test_is_windows_device_path {
70 use crate::is_windows_device_path;
71 use std::path::Path;
72
73 #[cfg_attr(not(windows), ignore = "only for Windows")]
74 #[test]
75 fn device_namespace() {
76 assert!(is_windows_device_path(Path::new(r"\\.\CON")))
77 }
78
79 #[cfg_attr(not(windows), ignore = "only for Windows")]
80 #[test]
81 fn reserved_device_name() {
82 assert!(is_windows_device_path(Path::new("NUL")))
83 }
84
85 #[cfg_attr(not(windows), ignore = "only for Windows")]
86 #[test]
87 fn normal_path() {
88 assert!(!is_windows_device_path(Path::new(r"dir\file")))
89 }
90
91 #[cfg_attr(not(windows), ignore = "only for Windows")]
92 #[test]
93 fn absolute_path() {
94 assert!(!is_windows_device_path(Path::new(r"\dir\file")))
95 }
96
97 #[cfg_attr(not(windows), ignore = "only for Windows")]
98 #[test]
99 fn unc_path() {
100 assert!(!is_windows_device_path(Path::new(r"\\server\share")))
101 }
102
103 #[cfg_attr(not(windows), ignore = "only for Windows")]
104 #[test]
105 fn verbatim_path() {
106 assert!(!is_windows_device_path(Path::new(r"\\?\dir\file")))
107 }
108}