axfs_ng_vfs/
types.rs

1use core::{fmt::Debug, time::Duration};
2
3/// Filesystem node type.
4#[repr(u8)]
5#[derive(Debug, Clone, Copy, Eq, PartialEq)]
6pub enum NodeType {
7    Unknown         = 0,
8    Fifo            = 0o1,
9    CharacterDevice = 0o2,
10    Directory       = 0o4,
11    BlockDevice     = 0o6,
12    RegularFile     = 0o10,
13    Symlink         = 0o12,
14    Socket          = 0o14,
15}
16
17impl From<u8> for NodeType {
18    fn from(value: u8) -> Self {
19        match value {
20            0o1 => Self::Fifo,
21            0o2 => Self::CharacterDevice,
22            0o4 => Self::Directory,
23            0o6 => Self::BlockDevice,
24            0o10 => Self::RegularFile,
25            0o12 => Self::Symlink,
26            0o14 => Self::Socket,
27            _ => Self::Unknown,
28        }
29    }
30}
31
32bitflags::bitflags! {
33    /// Inode permission mode.
34    #[derive(Debug, Clone, Copy)]
35    pub struct NodePermission: u16 {
36        /// Set user ID on execution.
37        const SET_UID = 0o4000;
38        /// Set group ID on execution.
39        const SET_GID = 0o2000;
40        /// Sticky bit.
41        const STICKY = 0o1000;
42
43        /// Owner has read permission.
44        const OWNER_READ = 0o400;
45        /// Owner has write permission.
46        const OWNER_WRITE = 0o200;
47        /// Owner has execute permission.
48        const OWNER_EXEC = 0o100;
49
50        /// Group has read permission.
51        const GROUP_READ = 0o40;
52        /// Group has write permission.
53        const GROUP_WRITE = 0o20;
54        /// Group has execute permission.
55        const GROUP_EXEC = 0o10;
56
57        /// Others have read permission.
58        const OTHER_READ = 0o4;
59        /// Others have write permission.
60        const OTHER_WRITE = 0o2;
61        /// Others have execute permission.
62        const OTHER_EXEC = 0o1;
63    }
64}
65
66impl Default for NodePermission {
67    fn default() -> Self {
68        Self::from_bits_truncate(0o666)
69    }
70}
71
72/// Filesystem node metadata.
73#[derive(Clone, Debug)]
74pub struct Metadata {
75    /// ID of device containing file
76    pub device: u64,
77    /// Inode number
78    pub inode: u64,
79    /// Number of hard links
80    pub nlink: u64,
81    /// Permission mode
82    pub mode: NodePermission,
83    /// Node type
84    pub node_type: NodeType,
85    /// User ID of owner
86    pub uid: u32,
87    /// Group ID of owner
88    pub gid: u32,
89    /// Total size in bytes
90    pub size: u64,
91    /// Block size for filesystem I/O
92    pub block_size: u64,
93    /// Number of 512B blocks allocated
94    pub blocks: u64,
95    /// Device ID (if special file)
96    pub rdev: DeviceId,
97
98    /// Time of last access
99    pub atime: Duration,
100    /// Time of last modification
101    pub mtime: Duration,
102    /// Time of last status change
103    pub ctime: Duration,
104}
105
106/// Filesystem node metadata update.
107#[derive(Default, Clone, Debug)]
108pub struct MetadataUpdate {
109    /// Permission mode
110    pub mode: Option<NodePermission>,
111    /// The owner (uid, gid)
112    pub owner: Option<(u32, u32)>,
113
114    /// Time of last access
115    pub atime: Option<Duration>,
116    /// Time of last modification
117    pub mtime: Option<Duration>,
118}
119
120/// Device Id
121#[derive(Default, Clone, PartialEq, Eq, Copy)]
122pub struct DeviceId(pub u64);
123
124impl DeviceId {
125    pub const fn new(major: u32, minor: u32) -> Self {
126        let major = major as u64;
127        let minor = minor as u64;
128        Self(
129            (major & 0xffff_f000) << 32
130                | (major & 0x0000_0fff) << 8
131                | (minor & 0xffff_ff00) << 12
132                | (minor & 0x0000_00ff),
133        )
134    }
135
136    pub const fn major(&self) -> u32 {
137        ((self.0 >> 32) & 0xffff_f000 | (self.0 >> 8) & 0x0000_0fff) as u32
138    }
139
140    pub const fn minor(&self) -> u32 {
141        ((self.0 >> 12) & 0xffff_ff00 | self.0 & 0x0000_00ff) as u32
142    }
143}
144
145impl Debug for DeviceId {
146    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
147        f.debug_struct("DeviceId")
148            .field("major", &self.major())
149            .field("minor", &self.minor())
150            .finish()
151    }
152}