Skip to content
Merged
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ The format is based on [Keep a Changelog] and this project adheres to [Semantic
- Raised the minimum supported Rust version to 1.87.0.
- Removed `core-error` feature as MSRV is now above 1.81
- Set edition to 2024
- Removed `Error::DeleteDirAsFile` (breaking change)
- Renamed `delete_file_in_dir` to `delete_entry_in_dir` because it can now delete empty directories (breaking change)

## [Version 0.9.0] - 2025-06-08

Expand Down
2 changes: 1 addition & 1 deletion examples/delete_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn main() -> Result<(), Error<std::io::Error>> {
let volume = volume_mgr.open_volume(VolumeIdx(0))?;
let root_dir = volume.open_root_dir()?;
println!("Deleting file {}...", FILE_TO_DELETE);
root_dir.delete_file_in_dir(FILE_TO_DELETE)?;
root_dir.delete_entry_in_dir(FILE_TO_DELETE)?;
println!("Deleted!");
Ok(())
}
Expand Down
51 changes: 26 additions & 25 deletions src/filesystem/directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ where
/// Open a directory.
///
/// You can then read the directory entries with `iterate_dir` and `open_file_in_dir`.
///
/// See [`VolumeManager::open_dir`] for details, except the directory
/// given is this directory.
pub fn open_dir<N>(
&self,
name: N,
Expand All @@ -134,7 +137,10 @@ where
Ok(())
}

/// Look in a directory for a named file.
/// Read the directory entry with the given filename from this directory, if it exists.
///
/// See [`VolumeManager::find_directory_entry`] for details, except the
/// directory given is this directory.
pub fn find_directory_entry<N>(&self, name: N) -> Result<DirEntry, Error<D::Error>>
where
N: ToShortFileName,
Expand All @@ -147,13 +153,8 @@ where
///
/// Long File Names will be ignored.
///
/// <div class="warning">
///
/// Do not attempt to call any methods on the VolumeManager or any of its
/// handles from inside the callback. You will get a lock error because the
/// object is already locked in order to do the iteration.
///
/// </div>
/// See [`VolumeManager::iterate_dir`] for details, except the directory
/// given is this directory.
pub fn iterate_dir<F>(&self, func: F) -> Result<(), Error<D::Error>>
where
F: FnMut(&DirEntry),
Expand All @@ -164,18 +165,8 @@ where
/// Call a callback function for each directory entry in a directory, and
/// process Long File Names.
///
/// You must supply a [`LfnBuffer`] this API can use to temporarily hold the
/// Long File Name. If you pass one that isn't large enough, any Long File
/// Names that don't fit will be ignored and presented as if they only had a
/// Short File Name.
///
/// <div class="warning">
///
/// Do not attempt to call any methods on the VolumeManager or any of its
/// handles from inside the callback. You will get a lock error because the
/// object is already locked in order to do the iteration.
///
/// </div>
/// See [`VolumeManager::iterate_dir_lfn`] for details, except the
/// directory given is this directory.
pub fn iterate_dir_lfn<F>(
&self,
lfn_buffer: &mut LfnBuffer<'_>,
Expand All @@ -188,7 +179,10 @@ where
.iterate_dir_lfn(self.raw_directory, lfn_buffer, func)
}

/// Open a file with the given full path. A file can only be opened once.
/// Open a file.
///
/// See [`VolumeManager::open_file_in_dir`] for details, except the
/// directory given is this directory.
pub fn open_file_in_dir<N>(
&self,
name: N,
Expand All @@ -203,15 +197,22 @@ where
Ok(f.to_file(self.volume_mgr))
}

/// Delete a closed file with the given filename, if it exists.
pub fn delete_file_in_dir<N>(&self, name: N) -> Result<(), Error<D::Error>>
/// Delete a file/directory.
///
/// See [`VolumeManager::delete_entry_in_dir`] for details, except the
/// directory given is this directory.
pub fn delete_entry_in_dir<N>(&self, name: N) -> Result<(), Error<D::Error>>
where
N: ToShortFileName,
{
self.volume_mgr.delete_file_in_dir(self.raw_directory, name)
self.volume_mgr
.delete_entry_in_dir(self.raw_directory, name)
}

/// Make a directory inside this directory
/// Create a new empty directory.
///
/// See [`VolumeManager::make_dir_in_dir`] for details, except the
/// directory given is this directory.
pub fn make_dir_in_dir<N>(&self, name: N) -> Result<(), Error<D::Error>>
where
N: ToShortFileName,
Expand Down
29 changes: 28 additions & 1 deletion src/filesystem/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl RawFile {
/// In contrast to a `RawFile`, a `File` holds a mutable reference to its
/// parent `VolumeManager`, which restricts which operations you can perform.
///
/// If you drop a value of this type, it closes the file automatically, and but
/// If you drop a value of this type, it closes the file automatically, but any
/// error that may occur will be ignored. To handle potential errors, use
/// the [`File::close`] method.
pub struct File<'a, D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize>
Expand Down Expand Up @@ -76,46 +76,70 @@ where
/// Read from the file
///
/// Returns how many bytes were read, or an error.
///
/// See [`VolumeManager::read`] for details, except the file given is this
/// file.
pub fn read(&self, buffer: &mut [u8]) -> Result<usize, crate::Error<D::Error>> {
self.volume_mgr.read(self.raw_file, buffer)
}

/// Write to the file
///
/// See [`VolumeManager::write`] for details, except the file given is this
/// file.
pub fn write(&self, buffer: &[u8]) -> Result<(), crate::Error<D::Error>> {
self.volume_mgr.write(self.raw_file, buffer)
}

/// Check if a file is at End Of File.
///
/// See [`VolumeManager::file_eof`] for details, except the file given is this
/// file.
pub fn is_eof(&self) -> bool {
self.volume_mgr
.file_eof(self.raw_file)
.expect("Corrupt file ID")
}

/// Seek a file with an offset from the current position.
///
/// See [`VolumeManager::file_seek_from_current`] for details, except the
/// file given is this file.
pub fn seek_from_current(&self, offset: i32) -> Result<(), crate::Error<D::Error>> {
self.volume_mgr
.file_seek_from_current(self.raw_file, offset)
}

/// Seek a file with an offset from the start of the file.
///
/// See [`VolumeManager::file_seek_from_start`] for details, except the
/// file given is this file.
pub fn seek_from_start(&self, offset: u32) -> Result<(), crate::Error<D::Error>> {
self.volume_mgr.file_seek_from_start(self.raw_file, offset)
}

/// Seek a file with an offset back from the end of the file.
///
/// See [`VolumeManager::file_seek_from_end`] for details, except the file
/// given is this file.
pub fn seek_from_end(&self, offset: u32) -> Result<(), crate::Error<D::Error>> {
self.volume_mgr.file_seek_from_end(self.raw_file, offset)
}

/// Get the length of a file
///
/// See [`VolumeManager::file_length`] for details, except the file given
/// is this file.
pub fn length(&self) -> u32 {
self.volume_mgr
.file_length(self.raw_file)
.expect("Corrupt file ID")
}

/// Get the current offset of a file
///
/// See [`VolumeManager::file_offset`] for details, except the file given
/// is this file.
pub fn offset(&self) -> u32 {
self.volume_mgr
.file_offset(self.raw_file)
Expand All @@ -130,6 +154,9 @@ where
}

/// Flush any written data by updating the directory entry.
///
/// See [`VolumeManager::flush_file`] for details, except the file given
/// is this file.
pub fn flush(&self) -> Result<(), Error<D::Error>> {
self.volume_mgr.flush_file(self.raw_file)
}
Expand Down
4 changes: 0 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,6 @@ where
OpenedDirAsFile,
/// You can't open a file as a directory
OpenedFileAsDir,
/// You can't delete a directory as a file [no longer being emitted]
DeleteDirAsFile,
/// You can't delete a non-empty directory
DeleteNonEmptyDir,
/// You can't close a volume with open files or directories
Expand Down Expand Up @@ -254,7 +252,6 @@ impl<E: Debug> embedded_io::Error for Error<E> {
Error::NotFound => ErrorKind::NotFound,
Error::OpenedDirAsFile
| Error::OpenedFileAsDir
| Error::DeleteDirAsFile
| Error::DeleteNonEmptyDir
| Error::BadCluster
| Error::ConversionError
Expand Down Expand Up @@ -294,7 +291,6 @@ where
Error::DirAlreadyOpen => write!(f, "directory already open"),
Error::OpenedDirAsFile => write!(f, "cannot open directory as file"),
Error::OpenedFileAsDir => write!(f, "cannot open file as directory"),
Error::DeleteDirAsFile => write!(f, "cannot delete directory as file"),
Error::DeleteNonEmptyDir => write!(f, "cannot delete a non-empty directory"),
Error::VolumeStillInUse => write!(f, "volume is still in use"),
Error::VolumeAlreadyOpen => write!(f, "cannot open volume twice"),
Expand Down
Loading