diff options
Diffstat (limited to 'toolkit/crashreporter/client/app/src/std/path.rs')
-rw-r--r-- | toolkit/crashreporter/client/app/src/std/path.rs | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/toolkit/crashreporter/client/app/src/std/path.rs b/toolkit/crashreporter/client/app/src/std/path.rs new file mode 100644 index 0000000000..c565615514 --- /dev/null +++ b/toolkit/crashreporter/client/app/src/std/path.rs @@ -0,0 +1,157 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//! We unfortunately have to mock `Path` because of `exists`, `try_exists`, and `metadata`. + +pub use std::path::*; + +use super::mock::MockKey; +use std::ffi::OsStr; + +macro_rules! delegate { + ( fn $name:ident (&self $(, $arg:ident : $argty:ty )* ) -> $ret:ty ) => { + pub fn $name (&self, $($arg : $ty)*) -> $ret { + self.0.$name($($arg),*) + } + } +} + +#[repr(transparent)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct Path(std::path::Path); + +impl AsRef<std::path::Path> for Path { + fn as_ref(&self) -> &std::path::Path { + &self.0 + } +} + +impl AsRef<OsStr> for Path { + fn as_ref(&self) -> &OsStr { + self.0.as_ref() + } +} + +impl AsRef<Path> for &str { + fn as_ref(&self) -> &Path { + Path::from_path(self.as_ref()) + } +} + +impl AsRef<Path> for String { + fn as_ref(&self) -> &Path { + Path::from_path(self.as_ref()) + } +} + +impl AsRef<Path> for &OsStr { + fn as_ref(&self) -> &Path { + Path::from_path(self.as_ref()) + } +} + +impl Path { + fn from_path(path: &std::path::Path) -> &Self { + // # Safety + // Transparent wrapper is safe to transmute. + unsafe { std::mem::transmute(path) } + } + + pub fn exists(&self) -> bool { + super::fs::MockFS + .try_get(|files| { + files + .path(self, false, |item| match &item.content { + super::fs::MockFSContent::File(r) => r.is_ok(), + _ => true, + }) + .unwrap_or(false) + }) + .unwrap_or(false) + } + + pub fn read_dir(&self) -> super::io::Result<super::fs::ReadDir> { + super::fs::ReadDir::new(&self.0) + } + + delegate!(fn display(&self) -> Display); + delegate!(fn file_stem(&self) -> Option<&OsStr>); + delegate!(fn file_name(&self) -> Option<&OsStr>); + delegate!(fn extension(&self) -> Option<&OsStr>); + + pub fn join<P: AsRef<Path>>(&self, path: P) -> PathBuf { + PathBuf(self.0.join(&path.as_ref().0)) + } + + pub fn parent(&self) -> Option<&Path> { + self.0.parent().map(Path::from_path) + } +} + +#[repr(transparent)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct PathBuf(pub(super) std::path::PathBuf); + +impl PathBuf { + pub fn set_extension<S: AsRef<OsStr>>(&mut self, extension: S) -> bool { + self.0.set_extension(extension) + } + + pub fn push<P: AsRef<Path>>(&mut self, path: P) { + self.0.push(path.as_ref()) + } + + pub fn pop(&mut self) -> bool { + self.0.pop() + } +} + +impl std::ops::Deref for PathBuf { + type Target = Path; + fn deref(&self) -> &Self::Target { + Path::from_path(self.0.as_ref()) + } +} + +impl AsRef<Path> for PathBuf { + fn as_ref(&self) -> &Path { + Path::from_path(self.0.as_ref()) + } +} + +impl AsRef<std::path::Path> for PathBuf { + fn as_ref(&self) -> &std::path::Path { + self.0.as_ref() + } +} + +impl AsRef<OsStr> for PathBuf { + fn as_ref(&self) -> &OsStr { + self.0.as_ref() + } +} + +impl From<std::ffi::OsString> for PathBuf { + fn from(os_str: std::ffi::OsString) -> Self { + PathBuf(os_str.into()) + } +} + +impl From<std::path::PathBuf> for PathBuf { + fn from(pathbuf: std::path::PathBuf) -> Self { + PathBuf(pathbuf) + } +} + +impl From<PathBuf> for std::ffi::OsString { + fn from(pathbuf: PathBuf) -> Self { + pathbuf.0.into() + } +} + +impl From<&str> for PathBuf { + fn from(s: &str) -> Self { + PathBuf(s.into()) + } +} |