1use core::{fmt::Debug, time::Duration};
2
3#[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 #[derive(Debug, Clone, Copy)]
35 pub struct NodePermission: u16 {
36 const SET_UID = 0o4000;
38 const SET_GID = 0o2000;
40 const STICKY = 0o1000;
42
43 const OWNER_READ = 0o400;
45 const OWNER_WRITE = 0o200;
47 const OWNER_EXEC = 0o100;
49
50 const GROUP_READ = 0o40;
52 const GROUP_WRITE = 0o20;
54 const GROUP_EXEC = 0o10;
56
57 const OTHER_READ = 0o4;
59 const OTHER_WRITE = 0o2;
61 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#[derive(Clone, Debug)]
74pub struct Metadata {
75 pub device: u64,
77 pub inode: u64,
79 pub nlink: u64,
81 pub mode: NodePermission,
83 pub node_type: NodeType,
85 pub uid: u32,
87 pub gid: u32,
89 pub size: u64,
91 pub block_size: u64,
93 pub blocks: u64,
95 pub rdev: DeviceId,
97
98 pub atime: Duration,
100 pub mtime: Duration,
102 pub ctime: Duration,
104}
105
106#[derive(Default, Clone, Debug)]
108pub struct MetadataUpdate {
109 pub mode: Option<NodePermission>,
111 pub owner: Option<(u32, u32)>,
113
114 pub atime: Option<Duration>,
116 pub mtime: Option<Duration>,
118}
119
120#[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}