/rust/registry/src/index.crates.io-1949cf8c6b5b557f/ignore-0.4.31/src/pathutil.rs
Line | Count | Source |
1 | | use std::{ffi::OsStr, path::Path}; |
2 | | |
3 | | use crate::walk::DirEntry; |
4 | | |
5 | | /// Returns true if and only if this path is considered to be hidden. |
6 | | /// |
7 | | /// # Platform behavior |
8 | | /// |
9 | | /// ## Windows |
10 | | /// |
11 | | /// This returns true if one of the following is true: |
12 | | /// |
13 | | /// * The base name of the path starts with a `.`. |
14 | | /// * The file attributes have the `HIDDEN` property set. |
15 | | /// |
16 | | /// ## All other platforms |
17 | | /// |
18 | | /// This only returns true if the base name of the path starts with a `.`. |
19 | 0 | pub(crate) fn is_hidden_path(dent: &Path) -> bool { |
20 | | #[cfg(not(windows))] |
21 | 0 | fn imp(path: &Path) -> bool { |
22 | 0 | is_hidden_path_only(path) |
23 | 0 | } |
24 | | |
25 | | #[cfg(windows)] |
26 | | fn imp(path: &Path) -> bool { |
27 | | use std::os::windows::fs::MetadataExt; |
28 | | use winapi_util::file; |
29 | | |
30 | | if let Ok(md) = path.metadata() { |
31 | | if file::is_hidden(md.file_attributes() as u64) { |
32 | | return true; |
33 | | } |
34 | | } |
35 | | is_hidden_path_only(path) |
36 | | } |
37 | | |
38 | 0 | imp(dent) |
39 | 0 | } |
40 | | |
41 | | /// Returns true if and only if this directory entry is considered to be |
42 | | /// hidden. |
43 | | /// |
44 | | /// # Platform behavior |
45 | | /// |
46 | | /// ## Windows |
47 | | /// |
48 | | /// This returns true if one of the following is true: |
49 | | /// |
50 | | /// * The base name of the path starts with a `.`. |
51 | | /// * The file attributes have the `HIDDEN` property set. |
52 | | /// |
53 | | /// ## All other platforms |
54 | | /// |
55 | | /// This only returns true if the base name of the path starts with a `.`. |
56 | 0 | pub(crate) fn is_hidden_entry(dent: &DirEntry) -> bool { |
57 | | #[cfg(not(windows))] |
58 | 0 | fn imp(dent: &DirEntry) -> bool { |
59 | 0 | is_hidden_path_only(dent.path()) |
60 | 0 | } |
61 | | |
62 | | #[cfg(windows)] |
63 | | fn imp(dent: &DirEntry) -> bool { |
64 | | use std::os::windows::fs::MetadataExt; |
65 | | use winapi_util::file; |
66 | | |
67 | | // This looks like we're doing an extra stat call, but on Windows, the |
68 | | // directory traverser reuses the metadata retrieved from each directory |
69 | | // entry and stores it on the DirEntry itself. So this is "free." |
70 | | if let Ok(md) = dent.metadata() { |
71 | | if file::is_hidden(md.file_attributes() as u64) { |
72 | | return true; |
73 | | } |
74 | | } |
75 | | is_hidden_path_only(dent.path()) |
76 | | } |
77 | | |
78 | 0 | imp(dent) |
79 | 0 | } |
80 | | |
81 | | /// Returns true if and only if this path is considered to be hidden from only |
82 | | /// the path itself. |
83 | | /// |
84 | | /// This has the same behavior on all platforms. |
85 | 0 | fn is_hidden_path_only(path: &Path) -> bool { |
86 | 0 | if let Some(name) = file_name(path) { |
87 | 0 | name.as_encoded_bytes().starts_with(b".") |
88 | | } else { |
89 | 0 | false |
90 | | } |
91 | 0 | } |
92 | | |
93 | | /// Strip `prefix` from the `path` and return the remainder. |
94 | | /// |
95 | | /// If `path` doesn't have a prefix `prefix`, then return `None`. |
96 | 0 | pub(crate) fn strip_prefix<'a, P: AsRef<Path> + ?Sized>( |
97 | 0 | prefix: &'a P, |
98 | 0 | path: &'a Path, |
99 | 0 | ) -> Option<&'a Path> { |
100 | | #[cfg(unix)] |
101 | 0 | fn imp<'a>(prefix: &'a Path, path: &'a Path) -> Option<&'a Path> { |
102 | | use std::os::unix::ffi::OsStrExt; |
103 | | |
104 | 0 | let prefix = prefix.as_os_str().as_bytes(); |
105 | 0 | let path = path.as_os_str().as_bytes(); |
106 | 0 | if prefix.len() > path.len() || prefix != &path[0..prefix.len()] { |
107 | 0 | None |
108 | | } else { |
109 | 0 | Some(&Path::new(OsStr::from_bytes(&path[prefix.len()..]))) |
110 | | } |
111 | 0 | } |
112 | | |
113 | | #[cfg(not(unix))] |
114 | | fn imp<'a>(prefix: &'a Path, path: &'a Path) -> Option<&'a Path> { |
115 | | path.strip_prefix(prefix).ok() |
116 | | } |
117 | | |
118 | 0 | imp(prefix.as_ref(), path) |
119 | 0 | } Unexecuted instantiation: ignore::pathutil::strip_prefix::<std::path::Path> Unexecuted instantiation: ignore::pathutil::strip_prefix::<std::path::PathBuf> Unexecuted instantiation: ignore::pathutil::strip_prefix::<str> |
120 | | |
121 | | /// Returns true if this file path is just a file name. i.e., Its parent is |
122 | | /// the empty string. |
123 | 0 | pub(crate) fn is_file_name<P: AsRef<Path>>(path: P) -> bool { |
124 | | #[cfg(unix)] |
125 | | { |
126 | 0 | memchr::memchr(b'/', path.as_ref().as_os_str().as_encoded_bytes()) |
127 | 0 | .is_none() |
128 | | } |
129 | | #[cfg(not(unix))] |
130 | | { |
131 | | path.as_ref() |
132 | | .parent() |
133 | | .map(|p| p.as_os_str().is_empty()) |
134 | | .unwrap_or(false) |
135 | | } |
136 | 0 | } |
137 | | |
138 | | /// The final component of the path, if it is a normal file. |
139 | | /// |
140 | | /// If the path terminates in `.`, `..`, or consists solely of a root of |
141 | | /// prefix, this will return `None`. |
142 | 0 | pub(crate) fn file_name<'a, P: AsRef<Path> + ?Sized>( |
143 | 0 | path: &'a P, |
144 | 0 | ) -> Option<&'a OsStr> { |
145 | | #[cfg(unix)] |
146 | 0 | fn imp(path: &Path) -> Option<&OsStr> { |
147 | | use std::os::unix::ffi::OsStrExt; |
148 | | |
149 | | use memchr::memrchr; |
150 | | |
151 | 0 | let path = path.as_os_str().as_bytes(); |
152 | 0 | if path.is_empty() { |
153 | 0 | return None; |
154 | 0 | } else if path.len() == 1 && path[0] == b'.' { |
155 | 0 | return None; |
156 | 0 | } else if path.last() == Some(&b'.') { |
157 | 0 | return None; |
158 | 0 | } else if path.len() >= 2 && &path[path.len() - 2..] == &b".."[..] { |
159 | 0 | return None; |
160 | 0 | } |
161 | 0 | let last_slash = memrchr(b'/', path).map(|i| i + 1).unwrap_or(0); |
162 | 0 | Some(OsStr::from_bytes(&path[last_slash..])) |
163 | 0 | } |
164 | | |
165 | | #[cfg(not(unix))] |
166 | | fn imp(path: &Path) -> Option<&OsStr> { |
167 | | path.file_name() |
168 | | } |
169 | | |
170 | 0 | imp(path.as_ref()) |
171 | 0 | } |