Skip to content

Commit

Permalink
Add exists method on Dir (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
aurelj authored Sep 20, 2024
1 parent 4bfe7b1 commit 4d2a2db
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
37 changes: 37 additions & 0 deletions embedded-fatfs/src/dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,43 @@ impl<'a, IO: ReadWriteSeek, TP: TimeProvider, OCC: OemCpConverter> Dir<'a, IO, T
}
}

/// Check to see if a file or directory with the given name exists
pub async fn exists(&self, path: &str) -> Result<bool, Error<IO::Error>> {
self.exists_internal(path, None).await
}

/// Check to see if a file with the given name exists
pub async fn file_exists(&self, path: &str) -> Result<bool, Error<IO::Error>> {
self.exists_internal(path, Some(false)).await
}

/// Check to see if a directory with the given name exists
pub async fn dir_exists(&self, path: &str) -> Result<bool, Error<IO::Error>> {
self.exists_internal(path, Some(true)).await
}

async fn exists_internal(&self, mut path: &str, is_dir: Option<bool>) -> Result<bool, Error<IO::Error>> {
let mut dir = self.clone();
// traverse path
while let (name, Some(rest)) = split_path(path) {
dir = dir.find_entry(name, Some(true), None).await?.to_dir();
path = rest;
}
let (name, _rest) = split_path(path);

// check if name exists and matches the is_dir flag
match dir.find_entry(name, None, None).await {
Ok(e) => match is_dir {
None => Ok(true),
Some(is_dir) => Ok(e.is_dir() == is_dir),
},
Err(e) => match e {
Error::NotFound => Ok(false),
_ => Err(e),
},
}
}

/// Opens existing subdirectory.
///
/// `path` is a '/' separated directory path relative to self directory.
Expand Down
40 changes: 40 additions & 0 deletions embedded-fatfs/tests/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,46 @@ async fn test_get_file_by_path_fat32() {
test_get_file_by_path(create_fs(FAT32_IMG).await).await
}

async fn test_exists(fs: FileSystem) {
let root_dir = fs.root_dir();

// check for existence of existing dir
assert_eq!(root_dir.exists("very/long/path").await.unwrap(), true);
assert_eq!(root_dir.file_exists("very/long/path").await.unwrap(), false);
assert_eq!(root_dir.dir_exists("very/long/path").await.unwrap(), true);
// check for existence of existing file
assert_eq!(root_dir.exists("very/long/path/test.txt").await.unwrap(), true);
assert_eq!(root_dir.file_exists("very/long/path/test.txt").await.unwrap(), true);
assert_eq!(root_dir.dir_exists("very/long/path/test.txt").await.unwrap(), false);
// check for existence of non existing file
assert_eq!(root_dir.exists("very/long/path/missing.txt").await.unwrap(), false);
assert_eq!(root_dir.file_exists("very/long/path/missing.txt").await.unwrap(), false);
assert_eq!(root_dir.dir_exists("very/long/path/missing.txt").await.unwrap(), false);
// check for existence of invalid path
assert!(root_dir.exists("very/missing/path/test.txt").await.is_err());
assert!(root_dir.file_exists("very/missing/path/test.txt").await.is_err());
assert!(root_dir.dir_exists("very/missing/path/test.txt").await.is_err());
// check for existence of invalid path containing file as non-last component
assert!(root_dir.exists("very/missing/path/test.txt/abc").await.is_err());
assert!(root_dir.file_exists("very/missing/path/test.txt/abc").await.is_err());
assert!(root_dir.dir_exists("very/missing/path/test.txt/abc").await.is_err());
}

#[tokio::test]
async fn test_exists_fat12() {
test_exists(create_fs(FAT12_IMG).await).await
}

#[tokio::test]
async fn test_exists_fat16() {
test_exists(create_fs(FAT16_IMG).await).await
}

#[tokio::test]
async fn test_exists_fat32() {
test_exists(create_fs(FAT32_IMG).await).await
}

async fn test_volume_metadata(fs: FileSystem, fat_type: FatType) {
assert_eq!(fs.volume_id(), 0x1234_5678);
assert_eq!(fs.volume_label(), "Test!");
Expand Down

0 comments on commit 4d2a2db

Please sign in to comment.