diff --git a/src/dir.rs b/src/dir.rs index 1be161a..ad1e851 100644 --- a/src/dir.rs +++ b/src/dir.rs @@ -88,7 +88,7 @@ fn split_path<'c>(path: &'c str) -> (&'c str, Option<&'c str>) { (comp, rest_opt) } -/// FAT directory +/// A FAT filesystem directory. pub struct Dir<'a, T: ReadWriteSeek + 'a> { stream: DirRawStream<'a, T>, fs: &'a FileSystem, @@ -99,7 +99,7 @@ impl <'a, T: ReadWriteSeek + 'a> Dir<'a, T> { Dir { stream, fs } } - /// Creates directory entries iterator + /// Creates directory entries iterator. pub fn iter(&self) -> DirIter<'a, T> { self.stream.clone(); DirIter { @@ -128,7 +128,9 @@ impl <'a, T: ReadWriteSeek + 'a> Dir<'a, T> { Err(io::Error::new(ErrorKind::NotFound, "file not found")) } - /// Opens existing directory + /// Opens existing subdirectory. + /// + /// `path` is a '/' separated directory path relative to self directory. pub fn open_dir(&self, path: &str) -> io::Result { let (name, rest_opt) = split_path(path); let e = self.find_entry(name, Some(true), None)?; @@ -139,6 +141,8 @@ impl <'a, T: ReadWriteSeek + 'a> Dir<'a, T> { } /// Opens existing file. + /// + /// `path` is a '/' separated file path relative to self directory. pub fn open_file(&self, path: &str) -> io::Result> { // traverse path let (name, rest_opt) = split_path(path); @@ -151,7 +155,10 @@ impl <'a, T: ReadWriteSeek + 'a> Dir<'a, T> { Ok(e.to_file()) } - /// Creates new file or opens existing without truncating. + /// Creates new or opens existing file=. + /// + /// `path` is a '/' separated file path relative to self directory. + /// File is never truncated when opening. It can be achieved by calling `File::truncate` method after opening. pub fn create_file(&self, path: &str) -> io::Result> { // traverse path let (name, rest_opt) = split_path(path); @@ -176,6 +183,8 @@ impl <'a, T: ReadWriteSeek + 'a> Dir<'a, T> { } /// Creates new directory or opens existing. + /// + /// `path` is a '/' separated path relative to self directory. pub fn create_dir(&self, path: &str) -> io::Result { // traverse path let (name, rest_opt) = split_path(path); @@ -226,6 +235,7 @@ impl <'a, T: ReadWriteSeek + 'a> Dir<'a, T> { /// Removes existing file or directory. /// + /// `path` is a '/' separated file path relative to self directory. /// Make sure there is no reference to this file (no File instance) or filesystem corruption /// can happen. pub fn remove(&self, path: &str) -> io::Result<()> { @@ -261,7 +271,9 @@ impl <'a, T: ReadWriteSeek + 'a> Dir<'a, T> { /// Renames or moves existing file or directory. /// - /// Destination directory can be cloned source directory in case of rename without moving operation. + /// `src_path` is a '/' separated source file path relative to self directory. + /// `dst_path` is a '/' separated destination file path relative to `dst_dir`. + /// `dst_dir` can be set to self directory if rename operation without moving is needed. /// Make sure there is no reference to this file (no File instance) or filesystem corruption /// can happen. pub fn rename(&self, src_path: &str, dst_dir: &Dir, dst_path: &str) -> io::Result<()> { diff --git a/src/dir_entry.rs b/src/dir_entry.rs index a8d77d2..ed77ce3 100644 --- a/src/dir_entry.rs +++ b/src/dir_entry.rs @@ -606,7 +606,7 @@ impl DirEntryEditor { /// FAT directory entry. /// -/// Returned by DirIter. +/// `DirEntry` is returned by `DirIter` when reading a directory. #[derive(Clone)] pub struct DirEntry<'a, T: ReadWriteSeek + 'a> { pub(crate) data: DirFileEntryData, @@ -619,7 +619,7 @@ pub struct DirEntry<'a, T: ReadWriteSeek + 'a> { } impl <'a, T: ReadWriteSeek> DirEntry<'a, T> { - /// Returns short file name + /// Returns short file name. #[cfg(feature = "alloc")] pub fn short_file_name(&self) -> String { self.short_name.to_str().to_string() @@ -643,7 +643,7 @@ impl <'a, T: ReadWriteSeek> DirEntry<'a, T> { self.short_file_name() } - /// Returns file attributes + /// Returns file attributes. pub fn attributes(&self) -> FileAttributes { self.data.attrs } @@ -666,7 +666,7 @@ impl <'a, T: ReadWriteSeek> DirEntry<'a, T> { DirEntryEditor::new(self.data.clone(), self.entry_pos) } - /// Returns File struct for this entry. + /// Returns `File` struct for this entry. /// /// Panics if this is not a file. pub fn to_file(&self) -> File<'a, T> { @@ -674,7 +674,7 @@ impl <'a, T: ReadWriteSeek> DirEntry<'a, T> { File::new(self.first_cluster(), Some(self.editor()), self.fs) } - /// Returns Dir struct for this entry. + /// Returns `Dir` struct for this entry. /// /// Panics if this is not a directory. pub fn to_dir(&self) -> Dir<'a, T> { diff --git a/src/file.rs b/src/file.rs index 4a9a78c..e50ae20 100644 --- a/src/file.rs +++ b/src/file.rs @@ -9,7 +9,7 @@ use dir_entry::{DirEntryEditor, DateTime, Date}; const MAX_FILE_SIZE: u32 = core::u32::MAX; -/// FAT file used for reading and writing. +/// A FAT filesystem file object used for reading and writing data. pub struct File<'a, T: ReadWriteSeek + 'a> { // Note first_cluster is None if file is empty first_cluster: Option, @@ -85,27 +85,27 @@ impl <'a, T: ReadWriteSeek> File<'a, T> { Ok(()) } - /// Set date and time of creation for this file. + /// Sets date and time of creation for this file. /// - /// Note: if chrono feature is enabled (default) library automatically updates all timestamps + /// Note: if `chrono` feature is enabled (default) library automatically updates all timestamps pub fn set_created(&mut self, date_time: DateTime) { if let Some(ref mut e) = self.entry { e.set_created(date_time); } } - /// Set date of last access for this file. + /// Sets date of last access for this file. /// - /// Note: if chrono feature is enabled (default) library automatically updates all timestamps + /// Note: if `chrono` feature is enabled (default) library automatically updates all timestamps pub fn set_accessed(&mut self, date: Date) { if let Some(ref mut e) = self.entry { e.set_accessed(date); } } - /// Set date and time of last modification for this file. + /// Sets date and time of last modification for this file. /// - /// Note: if chrono feature is enabled (default) library automatically updates all timestamps + /// Note: if `chrono` feature is enabled (default) library automatically updates all timestamps pub fn set_modified(&mut self, date_time: DateTime) { if let Some(ref mut e) = self.entry { e.set_modified(date_time); diff --git a/src/fs.rs b/src/fs.rs index 11d5d06..a90ab8f 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -20,6 +20,9 @@ use core::str; // http://wiki.osdev.org/FAT // https://www.win.tue.nl/~aeb/linux/fs/fat/fat-1.html +/// Type of FAT filesystem. +/// +/// `FatType` values are based on size of File Allocation Table entry. #[derive(Copy, Clone, Eq, PartialEq, Debug)] pub enum FatType { Fat12, Fat16, Fat32, @@ -37,6 +40,7 @@ impl FatType { } } +/// FAT volume status flags retrived from Boot Sector and allocation table. #[derive(Copy, Clone, Eq, PartialEq, Debug)] pub struct FsStatusFlags { pub(crate) dirty: bool, @@ -44,10 +48,14 @@ pub struct FsStatusFlags { } impl FsStatusFlags { + /// Checks if volume is marked as dirty. + /// + /// Dirty flag means volume has been suddenly ejected from filesystem without unmounting. pub fn dirty(&self) -> bool { self.dirty } + /// Checks if volume has IO Error flag active. pub fn io_error(&self) -> bool { self.io_error } @@ -290,7 +298,7 @@ impl FsInfoSector { } } -/// FAT filesystem options. +/// FAT filesystem mount options. #[derive(Copy, Clone, Debug)] pub struct FsOptions { pub(crate) update_accessed_date: bool, @@ -305,45 +313,45 @@ impl FsOptions { } } - /// If enabled library updates accessed date field in directory entry when reading + /// If enabled library updates accessed date field in directory entry when reading a file. pub fn update_accessed_date(mut self, enabled: bool) -> Self { self.update_accessed_date = enabled; self } - /// If enabled library updates FSInfo sector when unmounting + /// If enabled library updates FSInfo sector when unmounting (only if modified). pub fn update_fs_info(mut self, enabled: bool) -> Self { self.update_fs_info = enabled; self } } -/// FAT filesystem statistics +/// FAT volume statistics. #[derive(Copy, Clone, Eq, PartialEq, Debug)] pub struct FileSystemStats { - /// Cluster size in bytes cluster_size: u32, - /// Number of total clusters in filesystem usable for file allocation total_clusters: u32, - /// Number of free clusters free_clusters: u32, } impl FileSystemStats { + /// Cluster size in bytes pub fn cluster_size(&self) -> u32 { self.cluster_size } + /// Number of total clusters in filesystem usable for file allocation pub fn total_clusters(&self) -> u32 { self.total_clusters } + /// Number of free clusters pub fn free_clusters(&self) -> u32 { self.free_clusters } } -/// FAT filesystem main struct. +/// FAT filesystem struct. pub struct FileSystem { pub(crate) disk: RefCell, pub(crate) options: FsOptions, @@ -356,13 +364,13 @@ pub struct FileSystem { } impl FileSystem { - /// Creates new filesystem object instance. + /// Creates a new filesystem object instance. /// - /// Supplied disk parameter cannot be seeked. If there is a need to read a fragment of disk image (e.g. partition) - /// library user should provide a custom implementation of ReadWriteSeek trait. + /// Supplied `disk` parameter cannot be seeked. If there is a need to read a fragment of disk image (e.g. partition) + /// library user should wrap file handle in struct limiting access to partition bytes only e.g. `fscommon::StreamSlice`. /// /// Note: creating multiple filesystem objects with one underlying device/disk image can - /// cause filesystem corruption. + /// cause a filesystem corruption. pub fn new(mut disk: T, options: FsOptions) -> io::Result { // Make sure given image is not seeked debug_assert!(disk.seek(SeekFrom::Current(0))? == 0); @@ -416,19 +424,19 @@ impl FileSystem { }) } - /// Returns type of used File Allocation Table (FAT). + /// Returns a type of used File Allocation Table (FAT). pub fn fat_type(&self) -> FatType { self.fat_type } - /// Returns volume identifier read from BPB in Boot Sector. + /// Returns a volume identifier read from BPB in the Boot Sector. pub fn volume_id(&self) -> u32 { self.bpb.volume_id } - /// Returns volume label from BPB in Boot Sector. + /// Returns a volume label from BPB in the Boot Sector. /// - /// Note: File with VOLUME_ID attribute in root directory is ignored by this library. + /// Note: File with `VOLUME_ID` attribute in root directory is ignored by this library. /// Only label from BPB is used. #[cfg(feature = "alloc")] pub fn volume_label(&self) -> String { @@ -439,7 +447,7 @@ impl FileSystem { str::from_utf8(&self.bpb.volume_label).unwrap_or("").trim_right() } - /// Returns root directory object allowing futher penetration of filesystem structure. + /// Returns a root directory object allowing for futher penetration of a filesystem structure. pub fn root_dir<'b>(&'b self) -> Dir<'b, T> { let root_rdr = { match self.fat_type { @@ -526,7 +534,7 @@ impl FileSystem { /// Returns filesystem statistics like number of total and free clusters. /// /// For FAT32 volumes number of free clusters from FSInfo sector is returned (may be incorrect). - /// For other filesystems number is computed on each call (scans entire FAT so it takes more time). + /// For other filesystems number is computed on first call to this method. pub fn stats(&self) -> io::Result { let free_clusters_option = self.fs_info.borrow().free_cluster_count; let free_clusters = match free_clusters_option { @@ -540,7 +548,7 @@ impl FileSystem { }) } - // Forces free clusters recalculation + /// Forces free clusters recalculation. fn recalc_free_clusters(&self) -> io::Result { let mut fat = self.fat_slice(); let free_cluster_count = count_free_clusters(&mut fat, self.fat_type, self.total_clusters)?; @@ -548,7 +556,9 @@ impl FileSystem { Ok(free_cluster_count) } - /// Unmounts filesystem. Updates FSInfo sector if required in options. + /// Unmounts the filesystem. + /// + /// Updates FSInfo sector if `update_fs_info` mount option is enabled. pub fn unmount(self) -> io::Result<()> { self.unmount_internal() } @@ -572,6 +582,7 @@ impl FileSystem { } } +/// Tries to unmoun filesystem when dropping. impl Drop for FileSystem { fn drop(&mut self) { if let Err(err) = self.unmount_internal() {