use std::path::{Path, PathBuf};
#[cfg(test)]
use std::sync::Arc;
use std::{fmt, io};
#[cfg(test)]
use crate::pal::MockFilesystem;
use crate::pal::{BuildTargetFilesystem, Filesystem};
#[derive(Clone)]
pub(crate) enum FilesystemFacade {
Target(&'static BuildTargetFilesystem),
#[cfg(test)]
Mock(Arc<MockFilesystem>),
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg_attr(test, mutants::skip)]
impl fmt::Debug for FilesystemFacade {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Target(_) => f.debug_struct("FilesystemFacade::Target").finish(),
#[cfg(test)]
Self::Mock(_) => f.debug_struct("FilesystemFacade::Mock").finish(),
}
}
}
static BUILD_TARGET_FILESYSTEM: BuildTargetFilesystem = BuildTargetFilesystem;
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg_attr(test, mutants::skip)]
impl FilesystemFacade {
pub(crate) const fn target() -> Self {
Self::Target(&BUILD_TARGET_FILESYSTEM)
}
#[cfg(test)]
pub(crate) fn from_mock(mock: MockFilesystem) -> Self {
Self::Mock(Arc::new(mock))
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg_attr(test, mutants::skip)]
impl Filesystem for FilesystemFacade {
fn cargo_toml_exists(&self, dir: &Path) -> bool {
match self {
Self::Target(fs) => fs.cargo_toml_exists(dir),
#[cfg(test)]
Self::Mock(mock) => mock.cargo_toml_exists(dir),
}
}
fn read_cargo_toml(&self, dir: &Path) -> io::Result<String> {
match self {
Self::Target(fs) => fs.read_cargo_toml(dir),
#[cfg(test)]
Self::Mock(mock) => mock.read_cargo_toml(dir),
}
}
fn is_file(&self, path: &Path) -> bool {
match self {
Self::Target(fs) => fs.is_file(path),
#[cfg(test)]
Self::Mock(mock) => mock.is_file(path),
}
}
fn canonicalize(&self, path: &Path) -> io::Result<PathBuf> {
match self {
Self::Target(fs) => fs.canonicalize(path),
#[cfg(test)]
Self::Mock(mock) => mock.canonicalize(path),
}
}
fn current_dir(&self) -> io::Result<PathBuf> {
match self {
Self::Target(fs) => fs.current_dir(),
#[cfg(test)]
Self::Mock(mock) => mock.current_dir(),
}
}
fn exists(&self, path: &Path) -> bool {
match self {
Self::Target(fs) => fs.exists(path),
#[cfg(test)]
Self::Mock(mock) => mock.exists(path),
}
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg_attr(test, mutants::skip)]
impl Default for FilesystemFacade {
fn default() -> Self {
Self::target()
}
}