1 | //! which |
2 | //! |
3 | //! A Rust equivalent of Unix command `which(1)`. |
4 | //! # Example: |
5 | //! |
6 | //! To find which rustc executable binary is using: |
7 | //! |
8 | //! ```no_run |
9 | //! use which::which; |
10 | //! use std::path::PathBuf; |
11 | //! |
12 | //! let result = which("rustc" ).unwrap(); |
13 | //! assert_eq!(result, PathBuf::from("/usr/bin/rustc" )); |
14 | //! |
15 | //! ``` |
16 | |
17 | #![forbid (unsafe_code)] |
18 | |
19 | mod checker; |
20 | mod error; |
21 | mod finder; |
22 | #[cfg (windows)] |
23 | mod helper; |
24 | |
25 | #[cfg (feature = "regex" )] |
26 | use std::borrow::Borrow; |
27 | use std::env; |
28 | use std::fmt; |
29 | use std::path; |
30 | |
31 | use std::ffi::{OsStr, OsString}; |
32 | |
33 | use crate::checker::{CompositeChecker, ExecutableChecker, ExistedChecker}; |
34 | pub use crate::error::*; |
35 | use crate::finder::Finder; |
36 | |
37 | /// Find an executable binary's path by name. |
38 | /// |
39 | /// If given an absolute path, returns it if the file exists and is executable. |
40 | /// |
41 | /// If given a relative path, returns an absolute path to the file if |
42 | /// it exists and is executable. |
43 | /// |
44 | /// If given a string without path separators, looks for a file named |
45 | /// `binary_name` at each directory in `$PATH` and if it finds an executable |
46 | /// file there, returns it. |
47 | /// |
48 | /// # Example |
49 | /// |
50 | /// ```no_run |
51 | /// use which::which; |
52 | /// use std::path::PathBuf; |
53 | /// |
54 | /// let result = which::which("rustc" ).unwrap(); |
55 | /// assert_eq!(result, PathBuf::from("/usr/bin/rustc" )); |
56 | /// |
57 | /// ``` |
58 | pub fn which<T: AsRef<OsStr>>(binary_name: T) -> Result<path::PathBuf> { |
59 | which_all(binary_name).and_then(|mut i: impl Iterator | i.next().ok_or(err:Error::CannotFindBinaryPath)) |
60 | } |
61 | |
62 | /// Find an executable binary's path by name, ignoring `cwd`. |
63 | /// |
64 | /// If given an absolute path, returns it if the file exists and is executable. |
65 | /// |
66 | /// Does not resolve relative paths. |
67 | /// |
68 | /// If given a string without path separators, looks for a file named |
69 | /// `binary_name` at each directory in `$PATH` and if it finds an executable |
70 | /// file there, returns it. |
71 | /// |
72 | /// # Example |
73 | /// |
74 | /// ```no_run |
75 | /// use which::which; |
76 | /// use std::path::PathBuf; |
77 | /// |
78 | /// let result = which::which_global("rustc" ).unwrap(); |
79 | /// assert_eq!(result, PathBuf::from("/usr/bin/rustc" )); |
80 | /// |
81 | /// ``` |
82 | pub fn which_global<T: AsRef<OsStr>>(binary_name: T) -> Result<path::PathBuf> { |
83 | which_all_global(binary_name).and_then(|mut i: impl Iterator | i.next().ok_or(err:Error::CannotFindBinaryPath)) |
84 | } |
85 | |
86 | /// Find all binaries with `binary_name` using `cwd` to resolve relative paths. |
87 | pub fn which_all<T: AsRef<OsStr>>(binary_name: T) -> Result<impl Iterator<Item = path::PathBuf>> { |
88 | let cwd: Option = env::current_dir().ok(); |
89 | |
90 | let binary_checker: CompositeChecker = build_binary_checker(); |
91 | |
92 | let finder: Finder = Finder::new(); |
93 | |
94 | finder.find(binary_name, paths:env::var_os(key:"PATH" ), cwd, binary_checker) |
95 | } |
96 | |
97 | /// Find all binaries with `binary_name` ignoring `cwd`. |
98 | pub fn which_all_global<T: AsRef<OsStr>>( |
99 | binary_name: T, |
100 | ) -> Result<impl Iterator<Item = path::PathBuf>> { |
101 | let binary_checker: CompositeChecker = build_binary_checker(); |
102 | |
103 | let finder: Finder = Finder::new(); |
104 | |
105 | finder.find( |
106 | binary_name, |
107 | paths:env::var_os("PATH" ), |
108 | cwd:Option::<&Path>::None, |
109 | binary_checker, |
110 | ) |
111 | } |
112 | |
113 | /// Find all binaries matching a regular expression in a the system PATH. |
114 | /// |
115 | /// Only available when feature `regex` is enabled. |
116 | /// |
117 | /// # Arguments |
118 | /// |
119 | /// * `regex` - A regular expression to match binaries with |
120 | /// |
121 | /// # Examples |
122 | /// |
123 | /// Find Python executables: |
124 | /// |
125 | /// ```no_run |
126 | /// use regex::Regex; |
127 | /// use which::which; |
128 | /// use std::path::PathBuf; |
129 | /// |
130 | /// let re = Regex::new(r"python\d$").unwrap(); |
131 | /// let binaries: Vec<PathBuf> = which::which_re(re).unwrap().collect(); |
132 | /// let python_paths = vec![PathBuf::from("/usr/bin/python2"), PathBuf::from("/usr/bin/python3")]; |
133 | /// assert_eq!(binaries, python_paths); |
134 | /// ``` |
135 | /// |
136 | /// Find all cargo subcommand executables on the path: |
137 | /// |
138 | /// ``` |
139 | /// use which::which_re; |
140 | /// use regex::Regex; |
141 | /// |
142 | /// which_re(Regex::new("^cargo-.*").unwrap()).unwrap() |
143 | /// .for_each(|pth| println!("{}", pth.to_string_lossy())); |
144 | /// ``` |
145 | #[cfg (feature = "regex" )] |
146 | pub fn which_re(regex: impl Borrow<Regex>) -> Result<impl Iterator<Item = path::PathBuf>> { |
147 | which_re_in(regex, env::var_os("PATH" )) |
148 | } |
149 | |
150 | /// Find `binary_name` in the path list `paths`, using `cwd` to resolve relative paths. |
151 | pub fn which_in<T, U, V>(binary_name: T, paths: Option<U>, cwd: V) -> Result<path::PathBuf> |
152 | where |
153 | T: AsRef<OsStr>, |
154 | U: AsRef<OsStr>, |
155 | V: AsRef<path::Path>, |
156 | { |
157 | which_in_all(binary_name, paths, cwd) |
158 | .and_then(|mut i: impl Iterator | i.next().ok_or(err:Error::CannotFindBinaryPath)) |
159 | } |
160 | |
161 | /// Find all binaries matching a regular expression in a list of paths. |
162 | /// |
163 | /// Only available when feature `regex` is enabled. |
164 | /// |
165 | /// # Arguments |
166 | /// |
167 | /// * `regex` - A regular expression to match binaries with |
168 | /// * `paths` - A string containing the paths to search |
169 | /// (separated in the same way as the PATH environment variable) |
170 | /// |
171 | /// # Examples |
172 | /// |
173 | /// ```no_run |
174 | /// use regex::Regex; |
175 | /// use which::which; |
176 | /// use std::path::PathBuf; |
177 | /// |
178 | /// let re = Regex::new(r"python\d$").unwrap(); |
179 | /// let paths = Some("/usr/bin:/usr/local/bin"); |
180 | /// let binaries: Vec<PathBuf> = which::which_re_in(re, paths).unwrap().collect(); |
181 | /// let python_paths = vec![PathBuf::from("/usr/bin/python2"), PathBuf::from("/usr/bin/python3")]; |
182 | /// assert_eq!(binaries, python_paths); |
183 | /// ``` |
184 | #[cfg (feature = "regex" )] |
185 | pub fn which_re_in<T>( |
186 | regex: impl Borrow<Regex>, |
187 | paths: Option<T>, |
188 | ) -> Result<impl Iterator<Item = path::PathBuf>> |
189 | where |
190 | T: AsRef<OsStr>, |
191 | { |
192 | let binary_checker = build_binary_checker(); |
193 | |
194 | let finder = Finder::new(); |
195 | |
196 | finder.find_re(regex, paths, binary_checker) |
197 | } |
198 | |
199 | /// Find all binaries with `binary_name` in the path list `paths`, using `cwd` to resolve relative paths. |
200 | pub fn which_in_all<T, U, V>( |
201 | binary_name: T, |
202 | paths: Option<U>, |
203 | cwd: V, |
204 | ) -> Result<impl Iterator<Item = path::PathBuf>> |
205 | where |
206 | T: AsRef<OsStr>, |
207 | U: AsRef<OsStr>, |
208 | V: AsRef<path::Path>, |
209 | { |
210 | let binary_checker: CompositeChecker = build_binary_checker(); |
211 | |
212 | let finder: Finder = Finder::new(); |
213 | |
214 | finder.find(binary_name, paths, cwd:Some(cwd), binary_checker) |
215 | } |
216 | |
217 | /// Find all binaries with `binary_name` in the path list `paths`, ignoring `cwd`. |
218 | pub fn which_in_global<T, U>( |
219 | binary_name: T, |
220 | paths: Option<U>, |
221 | ) -> Result<impl Iterator<Item = path::PathBuf>> |
222 | where |
223 | T: AsRef<OsStr>, |
224 | U: AsRef<OsStr>, |
225 | { |
226 | let binary_checker: CompositeChecker = build_binary_checker(); |
227 | |
228 | let finder: Finder = Finder::new(); |
229 | |
230 | finder.find(binary_name, paths, cwd:Option::<&Path>::None, binary_checker) |
231 | } |
232 | |
233 | fn build_binary_checker() -> CompositeChecker { |
234 | CompositeCheckerCompositeChecker::new() |
235 | .add_checker(Box::new(ExistedChecker::new())) |
236 | .add_checker(Box::new(ExecutableChecker::new())) |
237 | } |
238 | |
239 | /// A wrapper containing all functionality in this crate. |
240 | pub struct WhichConfig { |
241 | cwd: Option<either::Either<bool, path::PathBuf>>, |
242 | custom_path_list: Option<OsString>, |
243 | binary_name: Option<OsString>, |
244 | #[cfg (feature = "regex" )] |
245 | regex: Option<Regex>, |
246 | } |
247 | |
248 | impl Default for WhichConfig { |
249 | fn default() -> Self { |
250 | Self { |
251 | cwd: Some(either::Either::Left(true)), |
252 | custom_path_list: None, |
253 | binary_name: None, |
254 | #[cfg (feature = "regex" )] |
255 | regex: None, |
256 | } |
257 | } |
258 | } |
259 | |
260 | #[cfg (feature = "regex" )] |
261 | type Regex = regex::Regex; |
262 | |
263 | #[cfg (not(feature = "regex" ))] |
264 | type Regex = (); |
265 | |
266 | impl WhichConfig { |
267 | pub fn new() -> Self { |
268 | Self::default() |
269 | } |
270 | |
271 | /// Whether or not to use the current working directory. `true` by default. |
272 | /// |
273 | /// # Panics |
274 | /// |
275 | /// If regex was set previously, and you've just passed in `use_cwd: true`, this will panic. |
276 | pub fn system_cwd(mut self, use_cwd: bool) -> Self { |
277 | #[cfg (feature = "regex" )] |
278 | if self.regex.is_some() && use_cwd { |
279 | panic!("which can't use regex and cwd at the same time!" ) |
280 | } |
281 | self.cwd = Some(either::Either::Left(use_cwd)); |
282 | self |
283 | } |
284 | |
285 | /// Sets a custom path for resolving relative paths. |
286 | /// |
287 | /// # Panics |
288 | /// |
289 | /// If regex was set previously, this will panic. |
290 | pub fn custom_cwd(mut self, cwd: path::PathBuf) -> Self { |
291 | #[cfg (feature = "regex" )] |
292 | if self.regex.is_some() { |
293 | panic!("which can't use regex and cwd at the same time!" ) |
294 | } |
295 | self.cwd = Some(either::Either::Right(cwd)); |
296 | self |
297 | } |
298 | |
299 | /// Sets the path name regex to search for. You ***MUST*** call this, or [`Self::binary_name`] prior to searching. |
300 | /// |
301 | /// When `Regex` is disabled this function takes the unit type as a stand in. The parameter will change when |
302 | /// `Regex` is enabled. |
303 | /// |
304 | /// # Panics |
305 | /// |
306 | /// If the `regex` feature wasn't turned on for this crate this will always panic. Additionally if a |
307 | /// `cwd` (aka current working directory) or `binary_name` was set previously, this will panic, as those options |
308 | /// are incompatible with `regex`. |
309 | #[allow (unused_variables)] |
310 | #[allow (unused_mut)] |
311 | pub fn regex(mut self, regex: Regex) -> Self { |
312 | #[cfg (not(feature = "regex" ))] |
313 | { |
314 | panic!("which's regex feature was not enabled in your Cargo.toml!" ) |
315 | } |
316 | #[cfg (feature = "regex" )] |
317 | { |
318 | if self.cwd != Some(either::Either::Left(false)) && self.cwd.is_some() { |
319 | panic!("which can't use regex and cwd at the same time!" ) |
320 | } |
321 | if self.binary_name.is_some() { |
322 | panic!("which can't use `binary_name` and `regex` at the same time!" ); |
323 | } |
324 | self.regex = Some(regex); |
325 | self |
326 | } |
327 | } |
328 | |
329 | /// Sets the path name to search for. You ***MUST*** call this, or [`Self::regex`] prior to searching. |
330 | /// |
331 | /// # Panics |
332 | /// |
333 | /// If a `regex` was set previously this will panic as this is not compatible with `regex`. |
334 | pub fn binary_name(mut self, name: OsString) -> Self { |
335 | #[cfg (feature = "regex" )] |
336 | if self.regex.is_some() { |
337 | panic!("which can't use `binary_name` and `regex` at the same time!" ); |
338 | } |
339 | self.binary_name = Some(name); |
340 | self |
341 | } |
342 | |
343 | /// Uses the given string instead of the `PATH` env variable. |
344 | pub fn custom_path_list(mut self, custom_path_list: OsString) -> Self { |
345 | self.custom_path_list = Some(custom_path_list); |
346 | self |
347 | } |
348 | |
349 | /// Uses the `PATH` env variable. Enabled by default. |
350 | pub fn system_path_list(mut self) -> Self { |
351 | self.custom_path_list = None; |
352 | self |
353 | } |
354 | |
355 | /// Finishes configuring, runs the query and returns the first result. |
356 | pub fn first_result(self) -> Result<path::PathBuf> { |
357 | self.all_results() |
358 | .and_then(|mut i| i.next().ok_or(Error::CannotFindBinaryPath)) |
359 | } |
360 | |
361 | /// Finishes configuring, runs the query and returns all results. |
362 | pub fn all_results(self) -> Result<impl Iterator<Item = path::PathBuf>> { |
363 | let binary_checker = build_binary_checker(); |
364 | |
365 | let finder = Finder::new(); |
366 | |
367 | let paths = self.custom_path_list.or_else(|| env::var_os("PATH" )); |
368 | |
369 | #[cfg (feature = "regex" )] |
370 | if let Some(regex) = self.regex { |
371 | return finder |
372 | .find_re(regex, paths, binary_checker) |
373 | .map(|i| Box::new(i) as Box<dyn Iterator<Item = path::PathBuf>>); |
374 | } |
375 | |
376 | let cwd = match self.cwd { |
377 | Some(either::Either::Left(false)) => None, |
378 | Some(either::Either::Right(custom)) => Some(custom), |
379 | None | Some(either::Either::Left(true)) => env::current_dir().ok(), |
380 | }; |
381 | |
382 | finder |
383 | .find( |
384 | self.binary_name.expect( |
385 | "binary_name not set! You must set binary_name or regex before searching!" , |
386 | ), |
387 | paths, |
388 | cwd, |
389 | binary_checker, |
390 | ) |
391 | .map(|i| Box::new(i) as Box<dyn Iterator<Item = path::PathBuf>>) |
392 | } |
393 | } |
394 | |
395 | /// An owned, immutable wrapper around a `PathBuf` containing the path of an executable. |
396 | /// |
397 | /// The constructed `PathBuf` is the output of `which` or `which_in`, but `which::Path` has the |
398 | /// advantage of being a type distinct from `std::path::Path` and `std::path::PathBuf`. |
399 | /// |
400 | /// It can be beneficial to use `which::Path` instead of `std::path::Path` when you want the type |
401 | /// system to enforce the need for a path that exists and points to a binary that is executable. |
402 | /// |
403 | /// Since `which::Path` implements `Deref` for `std::path::Path`, all methods on `&std::path::Path` |
404 | /// are also available to `&which::Path` values. |
405 | #[derive (Clone, PartialEq, Eq)] |
406 | pub struct Path { |
407 | inner: path::PathBuf, |
408 | } |
409 | |
410 | impl Path { |
411 | /// Returns the path of an executable binary by name. |
412 | /// |
413 | /// This calls `which` and maps the result into a `Path`. |
414 | pub fn new<T: AsRef<OsStr>>(binary_name: T) -> Result<Path> { |
415 | which(binary_name).map(|inner| Path { inner }) |
416 | } |
417 | |
418 | /// Returns the paths of all executable binaries by a name. |
419 | /// |
420 | /// this calls `which_all` and maps the results into `Path`s. |
421 | pub fn all<T: AsRef<OsStr>>(binary_name: T) -> Result<impl Iterator<Item = Path>> { |
422 | which_all(binary_name).map(|inner| inner.map(|inner| Path { inner })) |
423 | } |
424 | |
425 | /// Returns the path of an executable binary by name in the path list `paths` and using the |
426 | /// current working directory `cwd` to resolve relative paths. |
427 | /// |
428 | /// This calls `which_in` and maps the result into a `Path`. |
429 | pub fn new_in<T, U, V>(binary_name: T, paths: Option<U>, cwd: V) -> Result<Path> |
430 | where |
431 | T: AsRef<OsStr>, |
432 | U: AsRef<OsStr>, |
433 | V: AsRef<path::Path>, |
434 | { |
435 | which_in(binary_name, paths, cwd).map(|inner| Path { inner }) |
436 | } |
437 | |
438 | /// Returns all paths of an executable binary by name in the path list `paths` and using the |
439 | /// current working directory `cwd` to resolve relative paths. |
440 | /// |
441 | /// This calls `which_in_all` and maps the results into a `Path`. |
442 | pub fn all_in<T, U, V>( |
443 | binary_name: T, |
444 | paths: Option<U>, |
445 | cwd: V, |
446 | ) -> Result<impl Iterator<Item = Path>> |
447 | where |
448 | T: AsRef<OsStr>, |
449 | U: AsRef<OsStr>, |
450 | V: AsRef<path::Path>, |
451 | { |
452 | which_in_all(binary_name, paths, cwd).map(|inner| inner.map(|inner| Path { inner })) |
453 | } |
454 | |
455 | /// Returns a reference to a `std::path::Path`. |
456 | pub fn as_path(&self) -> &path::Path { |
457 | self.inner.as_path() |
458 | } |
459 | |
460 | /// Consumes the `which::Path`, yielding its underlying `std::path::PathBuf`. |
461 | pub fn into_path_buf(self) -> path::PathBuf { |
462 | self.inner |
463 | } |
464 | } |
465 | |
466 | impl fmt::Debug for Path { |
467 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
468 | fmt::Debug::fmt(&self.inner, f) |
469 | } |
470 | } |
471 | |
472 | impl std::ops::Deref for Path { |
473 | type Target = path::Path; |
474 | |
475 | fn deref(&self) -> &path::Path { |
476 | self.inner.deref() |
477 | } |
478 | } |
479 | |
480 | impl AsRef<path::Path> for Path { |
481 | fn as_ref(&self) -> &path::Path { |
482 | self.as_path() |
483 | } |
484 | } |
485 | |
486 | impl AsRef<OsStr> for Path { |
487 | fn as_ref(&self) -> &OsStr { |
488 | self.as_os_str() |
489 | } |
490 | } |
491 | |
492 | impl PartialEq<path::PathBuf> for Path { |
493 | fn eq(&self, other: &path::PathBuf) -> bool { |
494 | self.inner == *other |
495 | } |
496 | } |
497 | |
498 | impl PartialEq<Path> for path::PathBuf { |
499 | fn eq(&self, other: &Path) -> bool { |
500 | *self == other.inner |
501 | } |
502 | } |
503 | |
504 | /// An owned, immutable wrapper around a `PathBuf` containing the _canonical_ path of an |
505 | /// executable. |
506 | /// |
507 | /// The constructed `PathBuf` is the result of `which` or `which_in` followed by |
508 | /// `Path::canonicalize`, but `CanonicalPath` has the advantage of being a type distinct from |
509 | /// `std::path::Path` and `std::path::PathBuf`. |
510 | /// |
511 | /// It can be beneficial to use `CanonicalPath` instead of `std::path::Path` when you want the type |
512 | /// system to enforce the need for a path that exists, points to a binary that is executable, is |
513 | /// absolute, has all components normalized, and has all symbolic links resolved |
514 | /// |
515 | /// Since `CanonicalPath` implements `Deref` for `std::path::Path`, all methods on |
516 | /// `&std::path::Path` are also available to `&CanonicalPath` values. |
517 | #[derive (Clone, PartialEq, Eq)] |
518 | pub struct CanonicalPath { |
519 | inner: path::PathBuf, |
520 | } |
521 | |
522 | impl CanonicalPath { |
523 | /// Returns the canonical path of an executable binary by name. |
524 | /// |
525 | /// This calls `which` and `Path::canonicalize` and maps the result into a `CanonicalPath`. |
526 | pub fn new<T: AsRef<OsStr>>(binary_name: T) -> Result<CanonicalPath> { |
527 | which(binary_name) |
528 | .and_then(|p| p.canonicalize().map_err(|_| Error::CannotCanonicalize)) |
529 | .map(|inner| CanonicalPath { inner }) |
530 | } |
531 | |
532 | /// Returns the canonical paths of an executable binary by name. |
533 | /// |
534 | /// This calls `which_all` and `Path::canonicalize` and maps the results into `CanonicalPath`s. |
535 | pub fn all<T: AsRef<OsStr>>( |
536 | binary_name: T, |
537 | ) -> Result<impl Iterator<Item = Result<CanonicalPath>>> { |
538 | which_all(binary_name).map(|inner| { |
539 | inner.map(|inner| { |
540 | inner |
541 | .canonicalize() |
542 | .map_err(|_| Error::CannotCanonicalize) |
543 | .map(|inner| CanonicalPath { inner }) |
544 | }) |
545 | }) |
546 | } |
547 | |
548 | /// Returns the canonical path of an executable binary by name in the path list `paths` and |
549 | /// using the current working directory `cwd` to resolve relative paths. |
550 | /// |
551 | /// This calls `which_in` and `Path::canonicalize` and maps the result into a `CanonicalPath`. |
552 | pub fn new_in<T, U, V>(binary_name: T, paths: Option<U>, cwd: V) -> Result<CanonicalPath> |
553 | where |
554 | T: AsRef<OsStr>, |
555 | U: AsRef<OsStr>, |
556 | V: AsRef<path::Path>, |
557 | { |
558 | which_in(binary_name, paths, cwd) |
559 | .and_then(|p| p.canonicalize().map_err(|_| Error::CannotCanonicalize)) |
560 | .map(|inner| CanonicalPath { inner }) |
561 | } |
562 | |
563 | /// Returns all of the canonical paths of an executable binary by name in the path list `paths` and |
564 | /// using the current working directory `cwd` to resolve relative paths. |
565 | /// |
566 | /// This calls `which_in_all` and `Path::canonicalize` and maps the result into a `CanonicalPath`. |
567 | pub fn all_in<T, U, V>( |
568 | binary_name: T, |
569 | paths: Option<U>, |
570 | cwd: V, |
571 | ) -> Result<impl Iterator<Item = Result<CanonicalPath>>> |
572 | where |
573 | T: AsRef<OsStr>, |
574 | U: AsRef<OsStr>, |
575 | V: AsRef<path::Path>, |
576 | { |
577 | which_in_all(binary_name, paths, cwd).map(|inner| { |
578 | inner.map(|inner| { |
579 | inner |
580 | .canonicalize() |
581 | .map_err(|_| Error::CannotCanonicalize) |
582 | .map(|inner| CanonicalPath { inner }) |
583 | }) |
584 | }) |
585 | } |
586 | |
587 | /// Returns a reference to a `std::path::Path`. |
588 | pub fn as_path(&self) -> &path::Path { |
589 | self.inner.as_path() |
590 | } |
591 | |
592 | /// Consumes the `which::CanonicalPath`, yielding its underlying `std::path::PathBuf`. |
593 | pub fn into_path_buf(self) -> path::PathBuf { |
594 | self.inner |
595 | } |
596 | } |
597 | |
598 | impl fmt::Debug for CanonicalPath { |
599 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
600 | fmt::Debug::fmt(&self.inner, f) |
601 | } |
602 | } |
603 | |
604 | impl std::ops::Deref for CanonicalPath { |
605 | type Target = path::Path; |
606 | |
607 | fn deref(&self) -> &path::Path { |
608 | self.inner.deref() |
609 | } |
610 | } |
611 | |
612 | impl AsRef<path::Path> for CanonicalPath { |
613 | fn as_ref(&self) -> &path::Path { |
614 | self.as_path() |
615 | } |
616 | } |
617 | |
618 | impl AsRef<OsStr> for CanonicalPath { |
619 | fn as_ref(&self) -> &OsStr { |
620 | self.as_os_str() |
621 | } |
622 | } |
623 | |
624 | impl PartialEq<path::PathBuf> for CanonicalPath { |
625 | fn eq(&self, other: &path::PathBuf) -> bool { |
626 | self.inner == *other |
627 | } |
628 | } |
629 | |
630 | impl PartialEq<CanonicalPath> for path::PathBuf { |
631 | fn eq(&self, other: &CanonicalPath) -> bool { |
632 | *self == other.inner |
633 | } |
634 | } |
635 | |