1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
/* Copyright (c) 2018 Garrett Berg, vitiral@gmail.com * * Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or * http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or * http://opensource.org/licenses/MIT>, at your option. This file may not be * copied, modified, or distributed except according to those terms. */ //! The absolute path type, the root type for _most_ `Path*` types in this module //! (except for `PathArc`). use std::fmt; use std_prelude::*; use super::{PathArc, PathDir, PathFile, Result}; #[derive(Clone, Eq, Hash, PartialEq, PartialOrd, Ord)] /// An absolute (not _necessarily_ [canonicalized][1]) path that may or may not exist. /// /// [1]: https://doc.rust-lang.org/std/path/struct.Path.html?search=#method.canonicalize pub struct PathAbs(pub(crate) PathArc); impl PathAbs { /// Instantiate a new `PathAbs`. The path must exist or `io::Error` will be returned. /// /// # Examples /// ```rust /// use path_abs::PathAbs; /// /// # fn try_main() -> ::std::io::Result<()> { /// let lib = PathAbs::new("src/lib.rs")?; /// # Ok(()) } fn main() { try_main().unwrap() } /// ``` pub fn new<P: AsRef<Path>>(path: P) -> Result<PathAbs> { let arc = PathArc::new(path); arc.absolute() } /// Resolve the `PathAbs` as a `PathFile`. Return an error if it is not a file. pub fn into_file(self) -> Result<PathFile> { PathFile::from_abs(self) } /// Resolve the `PathAbs` as a `PathDir`. Return an error if it is not a directory. pub fn into_dir(self) -> Result<PathDir> { PathDir::from_abs(self) } /// Get the parent directory of this path as a `PathDir`. /// /// > This does not make aditional syscalls, as the parent by definition must be a directory /// > and exist. /// /// # Examples /// ```rust /// # extern crate path_abs; /// use path_abs::{PathDir, PathFile}; /// /// # fn try_main() -> ::std::io::Result<()> { /// let lib = PathFile::new("src/lib.rs")?; /// let src = lib.parent_dir().unwrap(); /// assert_eq!(PathDir::new("src")?, src); /// # Ok(()) } fn main() { try_main().unwrap() } /// ``` pub fn parent_dir(&self) -> Option<PathDir> { match self.parent() { Some(p) => Some(PathDir(PathAbs(PathArc::new(p)))), None => None, } } /// Return a reference to a basic `std::path::Path` pub fn as_path(&self) -> &Path { self.as_ref() } /// For constructing mocked paths during tests. This is effectively the same as a `PathBuf`. /// /// This is NOT checked for validity so the file may or may not actually exist and will /// NOT be, in any way, an absolute or canonicalized path. /// /// # Examples /// ```rust /// # extern crate path_abs; /// use path_abs::PathAbs; /// /// # fn try_main() -> ::std::io::Result<()> { /// // this file exist /// let lib = PathAbs::new("src/lib.rs")?; /// /// let lib_mocked = PathAbs::mock("src/lib.rs"); /// /// // in this case, the mocked file exists /// assert!(lib_mocked.exists()); /// /// // However, it is NOT equivalent to `lib` /// assert_ne!(lib, lib_mocked); /// /// // this file doesn't exist at all /// let dne = PathAbs::mock("src/dne.rs"); /// assert!(!dne.exists()); /// # Ok(()) } fn main() { try_main().unwrap() } /// ``` pub fn mock<P: AsRef<Path>>(fake_path: P) -> PathAbs { PathAbs(PathArc::new(fake_path)) } } impl fmt::Debug for PathAbs { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) } } impl AsRef<PathArc> for PathAbs { fn as_ref(&self) -> &PathArc { &self.0 } } impl AsRef<Path> for PathAbs { fn as_ref(&self) -> &Path { self.0.as_ref() } } impl AsRef<PathBuf> for PathAbs { fn as_ref(&self) -> &PathBuf { self.0.as_ref() } } impl Borrow<PathArc> for PathAbs { fn borrow(&self) -> &PathArc { self.as_ref() } } impl Borrow<Path> for PathAbs { fn borrow(&self) -> &Path { self.as_ref() } } impl Borrow<PathBuf> for PathAbs { fn borrow(&self) -> &PathBuf { self.as_ref() } } impl<'a> Borrow<PathArc> for &'a PathAbs { fn borrow(&self) -> &PathArc { self.as_ref() } } impl<'a> Borrow<Path> for &'a PathAbs { fn borrow(&self) -> &Path { self.as_ref() } } impl<'a> Borrow<PathBuf> for &'a PathAbs { fn borrow(&self) -> &PathBuf { self.as_ref() } } impl Deref for PathAbs { type Target = PathArc; fn deref(&self) -> &PathArc { &self.0 } } impl Into<PathArc> for PathAbs { fn into(self) -> PathArc { self.0 } }