1use core::fmt;
2
3const S_IFMT: u32 = 0o170000;
5const S_IFSOCK: u32 = 0o140000;
6const S_IFLNK: u32 = 0o120000;
7const S_IFREG: u32 = 0o100000;
8const S_IFBLK: u32 = 0o060000;
9const S_IFDIR: u32 = 0o040000;
10const S_IFCHR: u32 = 0o020000;
11const S_IFIFO: u32 = 0o010000;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub enum FileType {
20 Socket,
22 Symlink,
24 Regular,
26 BlockDevice,
28 Directory,
30 CharDevice,
32 Fifo,
34 Unknown(u32),
36}
37
38impl FileType {
39 pub fn from_mode(mode: u32) -> Self {
41 match mode & S_IFMT {
42 S_IFSOCK => FileType::Socket,
43 S_IFLNK => FileType::Symlink,
44 S_IFREG => FileType::Regular,
45 S_IFBLK => FileType::BlockDevice,
46 S_IFDIR => FileType::Directory,
47 S_IFCHR => FileType::CharDevice,
48 S_IFIFO => FileType::Fifo,
49 other => FileType::Unknown(other),
50 }
51 }
52
53 pub fn to_mode_bits(self) -> u32 {
55 match self {
56 FileType::Socket => S_IFSOCK,
57 FileType::Symlink => S_IFLNK,
58 FileType::Regular => S_IFREG,
59 FileType::BlockDevice => S_IFBLK,
60 FileType::Directory => S_IFDIR,
61 FileType::CharDevice => S_IFCHR,
62 FileType::Fifo => S_IFIFO,
63 FileType::Unknown(v) => v,
64 }
65 }
66}
67
68impl fmt::Display for FileType {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 match self {
71 FileType::Socket => write!(f, "socket"),
72 FileType::Symlink => write!(f, "symlink"),
73 FileType::Regular => write!(f, "regular file"),
74 FileType::BlockDevice => write!(f, "block device"),
75 FileType::Directory => write!(f, "directory"),
76 FileType::CharDevice => write!(f, "char device"),
77 FileType::Fifo => write!(f, "fifo"),
78 FileType::Unknown(v) => write!(f, "unknown({v:#o})"),
79 }
80 }
81}
82
83pub fn make_mode(file_type: FileType, permissions: u32) -> u32 {
87 file_type.to_mode_bits() | (permissions & 0o7777)
88}