Improve/fix API docs

This commit is contained in:
Rafał Harabień 2018-06-16 18:35:56 +02:00
parent 892c3974d3
commit 11a39fdaae
4 changed files with 60 additions and 37 deletions

View File

@ -88,7 +88,7 @@ fn split_path<'c>(path: &'c str) -> (&'c str, Option<&'c str>) {
(comp, rest_opt) (comp, rest_opt)
} }
/// FAT directory /// A FAT filesystem directory.
pub struct Dir<'a, T: ReadWriteSeek + 'a> { pub struct Dir<'a, T: ReadWriteSeek + 'a> {
stream: DirRawStream<'a, T>, stream: DirRawStream<'a, T>,
fs: &'a FileSystem<T>, fs: &'a FileSystem<T>,
@ -99,7 +99,7 @@ impl <'a, T: ReadWriteSeek + 'a> Dir<'a, T> {
Dir { stream, fs } Dir { stream, fs }
} }
/// Creates directory entries iterator /// Creates directory entries iterator.
pub fn iter(&self) -> DirIter<'a, T> { pub fn iter(&self) -> DirIter<'a, T> {
self.stream.clone(); self.stream.clone();
DirIter { DirIter {
@ -128,7 +128,9 @@ impl <'a, T: ReadWriteSeek + 'a> Dir<'a, T> {
Err(io::Error::new(ErrorKind::NotFound, "file not found")) 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<Self> { pub fn open_dir(&self, path: &str) -> io::Result<Self> {
let (name, rest_opt) = split_path(path); let (name, rest_opt) = split_path(path);
let e = self.find_entry(name, Some(true), None)?; let e = self.find_entry(name, Some(true), None)?;
@ -139,6 +141,8 @@ impl <'a, T: ReadWriteSeek + 'a> Dir<'a, T> {
} }
/// Opens existing file. /// Opens existing file.
///
/// `path` is a '/' separated file path relative to self directory.
pub fn open_file(&self, path: &str) -> io::Result<File<'a, T>> { pub fn open_file(&self, path: &str) -> io::Result<File<'a, T>> {
// traverse path // traverse path
let (name, rest_opt) = split_path(path); let (name, rest_opt) = split_path(path);
@ -151,7 +155,10 @@ impl <'a, T: ReadWriteSeek + 'a> Dir<'a, T> {
Ok(e.to_file()) 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<File<'a, T>> { pub fn create_file(&self, path: &str) -> io::Result<File<'a, T>> {
// traverse path // traverse path
let (name, rest_opt) = split_path(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. /// Creates new directory or opens existing.
///
/// `path` is a '/' separated path relative to self directory.
pub fn create_dir(&self, path: &str) -> io::Result<Self> { pub fn create_dir(&self, path: &str) -> io::Result<Self> {
// traverse path // traverse path
let (name, rest_opt) = split_path(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. /// 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 /// Make sure there is no reference to this file (no File instance) or filesystem corruption
/// can happen. /// can happen.
pub fn remove(&self, path: &str) -> io::Result<()> { 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. /// 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 /// Make sure there is no reference to this file (no File instance) or filesystem corruption
/// can happen. /// can happen.
pub fn rename(&self, src_path: &str, dst_dir: &Dir<T>, dst_path: &str) -> io::Result<()> { pub fn rename(&self, src_path: &str, dst_dir: &Dir<T>, dst_path: &str) -> io::Result<()> {

View File

@ -606,7 +606,7 @@ impl DirEntryEditor {
/// FAT directory entry. /// FAT directory entry.
/// ///
/// Returned by DirIter. /// `DirEntry` is returned by `DirIter` when reading a directory.
#[derive(Clone)] #[derive(Clone)]
pub struct DirEntry<'a, T: ReadWriteSeek + 'a> { pub struct DirEntry<'a, T: ReadWriteSeek + 'a> {
pub(crate) data: DirFileEntryData, pub(crate) data: DirFileEntryData,
@ -619,7 +619,7 @@ pub struct DirEntry<'a, T: ReadWriteSeek + 'a> {
} }
impl <'a, T: ReadWriteSeek> DirEntry<'a, T> { impl <'a, T: ReadWriteSeek> DirEntry<'a, T> {
/// Returns short file name /// Returns short file name.
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub fn short_file_name(&self) -> String { pub fn short_file_name(&self) -> String {
self.short_name.to_str().to_string() self.short_name.to_str().to_string()
@ -643,7 +643,7 @@ impl <'a, T: ReadWriteSeek> DirEntry<'a, T> {
self.short_file_name() self.short_file_name()
} }
/// Returns file attributes /// Returns file attributes.
pub fn attributes(&self) -> FileAttributes { pub fn attributes(&self) -> FileAttributes {
self.data.attrs self.data.attrs
} }
@ -666,7 +666,7 @@ impl <'a, T: ReadWriteSeek> DirEntry<'a, T> {
DirEntryEditor::new(self.data.clone(), self.entry_pos) 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. /// Panics if this is not a file.
pub fn to_file(&self) -> File<'a, T> { 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) 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. /// Panics if this is not a directory.
pub fn to_dir(&self) -> Dir<'a, T> { pub fn to_dir(&self) -> Dir<'a, T> {

View File

@ -9,7 +9,7 @@ use dir_entry::{DirEntryEditor, DateTime, Date};
const MAX_FILE_SIZE: u32 = core::u32::MAX; 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> { pub struct File<'a, T: ReadWriteSeek + 'a> {
// Note first_cluster is None if file is empty // Note first_cluster is None if file is empty
first_cluster: Option<u32>, first_cluster: Option<u32>,
@ -85,27 +85,27 @@ impl <'a, T: ReadWriteSeek> File<'a, T> {
Ok(()) 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) { pub fn set_created(&mut self, date_time: DateTime) {
if let Some(ref mut e) = self.entry { if let Some(ref mut e) = self.entry {
e.set_created(date_time); 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) { pub fn set_accessed(&mut self, date: Date) {
if let Some(ref mut e) = self.entry { if let Some(ref mut e) = self.entry {
e.set_accessed(date); 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) { pub fn set_modified(&mut self, date_time: DateTime) {
if let Some(ref mut e) = self.entry { if let Some(ref mut e) = self.entry {
e.set_modified(date_time); e.set_modified(date_time);

View File

@ -20,6 +20,9 @@ use core::str;
// http://wiki.osdev.org/FAT // http://wiki.osdev.org/FAT
// https://www.win.tue.nl/~aeb/linux/fs/fat/fat-1.html // 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)] #[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum FatType { pub enum FatType {
Fat12, Fat16, Fat32, 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)] #[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct FsStatusFlags { pub struct FsStatusFlags {
pub(crate) dirty: bool, pub(crate) dirty: bool,
@ -44,10 +48,14 @@ pub struct FsStatusFlags {
} }
impl 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 { pub fn dirty(&self) -> bool {
self.dirty self.dirty
} }
/// Checks if volume has IO Error flag active.
pub fn io_error(&self) -> bool { pub fn io_error(&self) -> bool {
self.io_error self.io_error
} }
@ -290,7 +298,7 @@ impl FsInfoSector {
} }
} }
/// FAT filesystem options. /// FAT filesystem mount options.
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct FsOptions { pub struct FsOptions {
pub(crate) update_accessed_date: bool, 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 { pub fn update_accessed_date(mut self, enabled: bool) -> Self {
self.update_accessed_date = enabled; self.update_accessed_date = enabled;
self 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 { pub fn update_fs_info(mut self, enabled: bool) -> Self {
self.update_fs_info = enabled; self.update_fs_info = enabled;
self self
} }
} }
/// FAT filesystem statistics /// FAT volume statistics.
#[derive(Copy, Clone, Eq, PartialEq, Debug)] #[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct FileSystemStats { pub struct FileSystemStats {
/// Cluster size in bytes
cluster_size: u32, cluster_size: u32,
/// Number of total clusters in filesystem usable for file allocation
total_clusters: u32, total_clusters: u32,
/// Number of free clusters
free_clusters: u32, free_clusters: u32,
} }
impl FileSystemStats { impl FileSystemStats {
/// Cluster size in bytes
pub fn cluster_size(&self) -> u32 { pub fn cluster_size(&self) -> u32 {
self.cluster_size self.cluster_size
} }
/// Number of total clusters in filesystem usable for file allocation
pub fn total_clusters(&self) -> u32 { pub fn total_clusters(&self) -> u32 {
self.total_clusters self.total_clusters
} }
/// Number of free clusters
pub fn free_clusters(&self) -> u32 { pub fn free_clusters(&self) -> u32 {
self.free_clusters self.free_clusters
} }
} }
/// FAT filesystem main struct. /// FAT filesystem struct.
pub struct FileSystem<T: ReadWriteSeek> { pub struct FileSystem<T: ReadWriteSeek> {
pub(crate) disk: RefCell<T>, pub(crate) disk: RefCell<T>,
pub(crate) options: FsOptions, pub(crate) options: FsOptions,
@ -356,13 +364,13 @@ pub struct FileSystem<T: ReadWriteSeek> {
} }
impl <T: ReadWriteSeek> FileSystem<T> { impl <T: ReadWriteSeek> FileSystem<T> {
/// 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) /// 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. /// 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 /// 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<Self> { pub fn new(mut disk: T, options: FsOptions) -> io::Result<Self> {
// Make sure given image is not seeked // Make sure given image is not seeked
debug_assert!(disk.seek(SeekFrom::Current(0))? == 0); debug_assert!(disk.seek(SeekFrom::Current(0))? == 0);
@ -416,19 +424,19 @@ impl <T: ReadWriteSeek> FileSystem<T> {
}) })
} }
/// Returns type of used File Allocation Table (FAT). /// Returns a type of used File Allocation Table (FAT).
pub fn fat_type(&self) -> FatType { pub fn fat_type(&self) -> FatType {
self.fat_type 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 { pub fn volume_id(&self) -> u32 {
self.bpb.volume_id 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. /// Only label from BPB is used.
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub fn volume_label(&self) -> String { pub fn volume_label(&self) -> String {
@ -439,7 +447,7 @@ impl <T: ReadWriteSeek> FileSystem<T> {
str::from_utf8(&self.bpb.volume_label).unwrap_or("").trim_right() 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> { pub fn root_dir<'b>(&'b self) -> Dir<'b, T> {
let root_rdr = { let root_rdr = {
match self.fat_type { match self.fat_type {
@ -526,7 +534,7 @@ impl <T: ReadWriteSeek> FileSystem<T> {
/// Returns filesystem statistics like number of total and free clusters. /// 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 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<FileSystemStats> { pub fn stats(&self) -> io::Result<FileSystemStats> {
let free_clusters_option = self.fs_info.borrow().free_cluster_count; let free_clusters_option = self.fs_info.borrow().free_cluster_count;
let free_clusters = match free_clusters_option { let free_clusters = match free_clusters_option {
@ -540,7 +548,7 @@ impl <T: ReadWriteSeek> FileSystem<T> {
}) })
} }
// Forces free clusters recalculation /// Forces free clusters recalculation.
fn recalc_free_clusters(&self) -> io::Result<u32> { fn recalc_free_clusters(&self) -> io::Result<u32> {
let mut fat = self.fat_slice(); let mut fat = self.fat_slice();
let free_cluster_count = count_free_clusters(&mut fat, self.fat_type, self.total_clusters)?; let free_cluster_count = count_free_clusters(&mut fat, self.fat_type, self.total_clusters)?;
@ -548,7 +556,9 @@ impl <T: ReadWriteSeek> FileSystem<T> {
Ok(free_cluster_count) 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<()> { pub fn unmount(self) -> io::Result<()> {
self.unmount_internal() self.unmount_internal()
} }
@ -572,6 +582,7 @@ impl <T: ReadWriteSeek> FileSystem<T> {
} }
} }
/// Tries to unmoun filesystem when dropping.
impl<T: ReadWriteSeek> Drop for FileSystem<T> { impl<T: ReadWriteSeek> Drop for FileSystem<T> {
fn drop(&mut self) { fn drop(&mut self) {
if let Err(err) = self.unmount_internal() { if let Err(err) = self.unmount_internal() {