From 71a1a8b73099822887e697fd2dee0071e2354ac4 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 7 May 2024 11:35:10 +0200 Subject: [PATCH] feat(dir): Allow converting Path to InMemoryDir --- crates/snapbox/src/dir/dir.rs | 41 +++++++++++++++++++++++++++++++- crates/snapbox/src/dir/mod.rs | 2 ++ crates/snapbox/src/dir/source.rs | 39 ++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 crates/snapbox/src/dir/source.rs diff --git a/crates/snapbox/src/dir/dir.rs b/crates/snapbox/src/dir/dir.rs index a3012090..2e39d96f 100644 --- a/crates/snapbox/src/dir/dir.rs +++ b/crates/snapbox/src/dir/dir.rs @@ -1,3 +1,4 @@ +use super::DirSource; use super::FileType; /// Collection of files @@ -94,9 +95,15 @@ impl Dir for std::ffi::OsString { #[derive(Clone, Debug, PartialEq, Eq)] pub struct InMemoryDir { content: std::collections::BTreeMap, + source: DirSource, } impl InMemoryDir { + fn with_source(mut self, source: impl Into) -> Self { + self.source = source.into(); + self + } + /// Initialize a test fixture directory `root` pub fn write_to_path(&self, root: &std::path::Path) -> Result<(), crate::assert::Error> { for (relpath, entry) in &self.content { @@ -107,6 +114,30 @@ impl InMemoryDir { } } +impl From<&'_ std::path::Path> for InMemoryDir { + fn from(root: &'_ std::path::Path) -> Self { + PathIter::infer_iter(root) + .collect::() + .with_source(DirSource::path(root)) + } +} + +impl From<&'_ std::path::PathBuf> for InMemoryDir { + fn from(root: &'_ std::path::PathBuf) -> Self { + PathIter::infer_iter(root.as_path()) + .collect::() + .with_source(DirSource::path(root)) + } +} + +impl From for InMemoryDir { + fn from(root: std::path::PathBuf) -> Self { + PathIter::infer_iter(root.as_path()) + .collect::() + .with_source(DirSource::path(root)) + } +} + pub type InMemoryDirIter = std::collections::btree_map::IntoIter; impl FromIterator<(P, E)> for InMemoryDir @@ -154,7 +185,10 @@ where } } } - Self { content } + Self { + content, + source: DirSource::inmemory(), + } } } @@ -167,6 +201,11 @@ pub struct PathIter { } impl PathIter { + fn infer_iter(root: &std::path::Path) -> Self { + let binary = false; + Self::iter_(root, binary) + } + fn binary_iter(root: &std::path::Path) -> Self { let binary = true; Self::iter_(root, binary) diff --git a/crates/snapbox/src/dir/mod.rs b/crates/snapbox/src/dir/mod.rs index 9ad09062..7c9ab5b3 100644 --- a/crates/snapbox/src/dir/mod.rs +++ b/crates/snapbox/src/dir/mod.rs @@ -6,6 +6,7 @@ mod diff; mod dir; mod ops; mod root; +mod source; #[cfg(test)] mod tests; @@ -24,6 +25,7 @@ pub use dir::PathIter; pub use ops::resolve_dir; pub use ops::strip_trailing_slash; pub use root::DirRoot; +pub use source::DirSource; #[cfg(feature = "dir")] pub(crate) use ops::canonicalize; diff --git a/crates/snapbox/src/dir/source.rs b/crates/snapbox/src/dir/source.rs new file mode 100644 index 00000000..676da2ac --- /dev/null +++ b/crates/snapbox/src/dir/source.rs @@ -0,0 +1,39 @@ +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct DirSource { + inner: DirSourceInner, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +enum DirSourceInner { + InMemory, + Path(std::path::PathBuf), +} + +impl DirSource { + pub(crate) fn inmemory() -> Self { + Self { + inner: DirSourceInner::InMemory, + } + } + + pub fn is_inmemory(&self) -> bool { + matches!(self.inner, DirSourceInner::InMemory) + } + + pub fn path(path: impl Into) -> Self { + Self { + inner: DirSourceInner::Path(path.into()), + } + } + + pub fn is_path(&self) -> bool { + self.as_path().is_some() + } + + pub fn as_path(&self) -> Option<&std::path::Path> { + match &self.inner { + DirSourceInner::Path(value) => Some(value.as_ref()), + _ => None, + } + } +}