use std::fmt::{self, Debug, Display};
use std::str::FromStr;
#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
use crate::{Error, Result, error};
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(rename_all = "kebab-case"))]
pub enum FileType
{
#[default]
Regular,
Directory,
Symlink,
Block,
Character,
Socket,
Fifo
}
impl TryFrom<libc::mode_t> for FileType
{
type Error = Error;
fn try_from(m: libc::mode_t) -> Result<Self>
{
match m & libc::S_IFMT
{
libc::S_IFREG => Ok(Self::Regular),
libc::S_IFDIR => Ok(Self::Directory),
libc::S_IFLNK => Ok(Self::Symlink),
libc::S_IFSOCK => Ok(Self::Socket),
libc::S_IFCHR => Ok(Self::Character),
libc::S_IFBLK => Ok(Self::Block),
libc::S_IFIFO => Ok(Self::Fifo),
_ => error!("unable to determine file type from libc::mode_t")
}
}
}
impl Display for FileType
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "{}", match self
{
Self::Regular => "regular",
Self::Directory => "directory",
Self::Symlink => "link",
Self::Socket => "socket",
Self::Fifo => "fifo",
Self::Character => "character",
Self::Block => "block"
})
}
}
impl FromStr for FileType
{
type Err = Error;
fn from_str(s: &str) -> Result<Self>
{
match s
{
"regular" => Ok(Self::Regular),
"directory" => Ok(Self::Directory),
"link" => Ok(Self::Symlink),
"socket" => Ok(Self::Socket),
"fifo" => Ok(Self::Fifo),
"character" => Ok(Self::Character),
"block" => Ok(Self::Block),
_ => error!("unknown file type: '{s}'")
}
}
}