Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix trussed-dev/littlefs#35 #3

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ impl From<ll::lfs_info> for Metadata
}
}

struct RemoveDirAllProgress {
files_removed: usize,
skipped_any: bool,
}

impl<Storage: driver::Storage> Filesystem<'_, Storage> {

pub fn allocate() -> Allocation<Storage> {
Expand Down Expand Up @@ -315,14 +320,21 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
self.remove_dir_all_where(path, &|_| true).map(|_| ())
}

#[cfg(feature = "dir-entry-path")]
pub fn remove_dir_all_where<P>(&self, path: &Path, predicate: &P) -> Result<usize>
/// Returns number of deleted files + whether the directory was fully deleted or not
fn remove_dir_all_where_inner<P>(
&self,
path: &Path,
predicate: &P,
) -> Result<RemoveDirAllProgress>
where
P: Fn(&DirEntry) -> bool,
{
if !path.exists(self) {
debug_now!("no such directory {}, early return", path);
return Ok(0);
return Ok(RemoveDirAllProgress {
files_removed: 0,
skipped_any: false,
});
}
let mut skipped_any = false;
let mut files_removed = 0;
Expand All @@ -345,7 +357,9 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
}
if entry.file_type().is_dir() {
debug_now!("recursing into directory {}", &entry.path());
files_removed += self.remove_dir_all_where(entry.path(), predicate)?;
let progress = self.remove_dir_all_where_inner(entry.path(), predicate)?;
files_removed += progress.files_removed;
skipped_any |= progress.skipped_any;
debug_now!("...back");
}
}
Expand All @@ -356,7 +370,19 @@ impl<Storage: driver::Storage> Filesystem<'_, Storage> {
self.remove_dir(path)?;
debug_now!("..worked");
}
Ok(files_removed)
Ok(RemoveDirAllProgress {
files_removed,
skipped_any,
})
}

#[cfg(feature = "dir-entry-path")]
pub fn remove_dir_all_where<P>(&self, path: &Path, predicate: &P) -> Result<usize>
where
P: Fn(&DirEntry) -> bool,
{
self.remove_dir_all_where_inner(path, predicate)
.map(|progress| progress.files_removed)
}

/// Rename or move a file or directory.
Expand Down
1 change: 1 addition & 0 deletions src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::consts;
/// accepts arbitrary C strings), but the assumption makes `AsRef<str>` trivial
/// to implement.
#[derive(PartialEq, Eq)]
#[repr(transparent)]
pub struct Path {
inner: CStr,
}
Expand Down
30 changes: 30 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::{
Read,
SeekFrom,
},
path::Path,
driver,
};

Expand Down Expand Up @@ -347,6 +348,35 @@ fn test_fancy_open() {
assert_eq!(&buf, b"world");
}

#[test]
fn remove_dir_all_where() {
let mut backend = Ram::default();
let mut storage = RamStorage::new(&mut backend);

Filesystem::format(&mut storage).unwrap();

Filesystem::mount_and_then(&mut storage, |fs| {
fs.write(path!("test_file"), b"some data").unwrap();
fs.create_dir(path!("test_dir")).unwrap();
fs.write(path!("test_dir/test_file"), b"some_inner_data")
.unwrap();
fs.write(path!("test_dir/test_file2"), b"some_inner_data")
.unwrap();
fs.remove_dir_all_where(path!(""), &|entry| {
entry.path() != path!("test_dir/test_file")
})
.unwrap();
assert!(fs.metadata(path!("test_dir/test_file")).unwrap().is_file());
assert_eq!(fs.metadata(path!("test_file")), Err(Error::NoSuchEntry));
assert_eq!(
fs.metadata(path!("test_dir/test_file2")),
Err(Error::NoSuchEntry)
);
Ok(())
})
.unwrap();
}

#[test]
fn attributes() {
let mut backend = Ram::default();
Expand Down