diskit 0.1.1

Utilities for intercepting disk requests.
Documentation
//! Transparent replica of [`Metadata`](std::fs::Metadata)
//!
//! For more information see the [struct level documentation](Metadata).

use std::fs;

/// Type of a file on disk
///
/// There are currently there forms of files supported by this
/// library: [`File`](Self::File), [`Dir`](Self::Dir) and
/// [`Symlink`](Self::Symlink) (please notice that
/// [`VirtualDiskit`](crate::VirtualDiskit) does not support
/// symlinks).
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum FileType
{
    /// A normal file
    File,
    /// A directory
    Dir,
    /// A symbolic link
    Symlink,
}

/// Transparent replica of [`Metadata`](std::fs::Metadata)
///
/// This is a [replica](crate#making-your-own-diskit) of
/// [`Metadata`](std::fs::Metadata).  It stores just the [`FileType`]
/// and the length of the file.
// See lib.rs for justification.
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Metadata
{
    pub file_type: FileType,
    pub len: u64,
}

impl FileType
{
    /// Returns whether the file is a directory
    ///
    /// This function returns whether the file is a directory.
    #[must_use]
    pub fn is_dir(&self) -> bool
    {
        *self == Self::Dir
    }

    /// Returns whether the file is a normal file
    ///
    /// This function returns whether the file is a normal file.
    #[must_use]
    pub fn is_file(&self) -> bool
    {
        *self == Self::File
    }

    /// Returns whether the file is a symlink
    ///
    /// This function returns whether the file is a symlink.
    #[must_use]
    pub fn is_symlink(&self) -> bool
    {
        *self == Self::Symlink
    }
}

impl Metadata
{
    /// Returns the file type
    ///
    /// This function returns the file type.
    #[must_use]
    pub const fn file_type(&self) -> FileType
    {
        self.file_type
    }

    /// Returns whether the file is a directory
    ///
    /// This function returns whether the file is a directory.
    #[must_use]
    pub fn is_dir(&self) -> bool
    {
        self.file_type == FileType::Dir
    }

    /// Returns whether the file is a normal file
    ///
    /// This function returns whether the file is a normal file.
    #[must_use]
    pub fn is_file(&self) -> bool
    {
        self.file_type == FileType::File
    }

    /// Returns whether the file is a symlink
    ///
    /// This function returns whether the file is a symlink.
    #[must_use]
    pub fn is_symlink(&self) -> bool
    {
        self.file_type == FileType::Symlink
    }

    /// Returns the length of the file
    ///
    /// This function returns the length of the file (in bytes).  The
    /// length of a directory is always `0`, not `4096` or the number of
    /// entries.
    #[must_use]
    pub const fn len(&self) -> u64
    {
        self.len
    }

    /// Returns whether the file is empty
    ///
    /// This function returns whether the length of this file as
    /// returned by [`Metadata::len`] is zero or not.
    #[must_use]
    pub const fn is_empty(&self) -> bool
    {
        self.len == 0
    }
}

impl From<fs::Metadata> for Metadata
{
    fn from(metadata: fs::Metadata) -> Self
    {
        Self {
            file_type: if metadata.is_dir()
            {
                FileType::Dir
            }
            else if metadata.is_file()
            {
                FileType::File
            }
            else
            {
                FileType::Symlink
            },
            len: metadata.len(),
        }
    }
}