file_system/fundamentals/
metadata.rs1use users::{GroupIdentifier, UserIdentifier};
2
3use crate::{Kind, Permissions, Time};
4
5use super::Inode;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct Metadata {
19 inode: Option<Inode>,
21 r#type: Kind,
23 creation_time: Time,
25 modification_time: Time,
27 access_time: Time,
29 permissions: Permissions,
31 user: UserIdentifier,
33 group: GroupIdentifier,
35}
36
37impl Metadata {
38 pub const IDENTIFIER: u8 = 0x01;
39
40 pub fn get_default(
41 type_value: Kind,
42 current_time: Time,
43 user: UserIdentifier,
44 group: GroupIdentifier,
45 ) -> Option<Self> {
46 let permissions = Permissions::new_default(type_value);
47
48 Some(Metadata {
49 inode: None,
50 r#type: type_value,
51 creation_time: current_time,
52 modification_time: current_time,
53 access_time: current_time,
54 permissions,
55 user,
56 group,
57 })
58 }
59
60 pub fn get_inode(&self) -> Option<Inode> {
61 self.inode
62 }
63
64 pub fn get_type(&self) -> Kind {
65 self.r#type
66 }
67
68 pub fn get_creation_time(&self) -> Time {
69 self.creation_time
70 }
71
72 pub fn get_modification_time(&self) -> Time {
73 self.modification_time
74 }
75
76 pub fn get_access_time(&self) -> Time {
77 self.access_time
78 }
79
80 pub fn get_permissions(&self) -> Permissions {
81 self.permissions
82 }
83
84 pub fn get_user(&self) -> UserIdentifier {
85 self.user
86 }
87
88 pub fn get_group(&self) -> GroupIdentifier {
89 self.group
90 }
91
92 pub fn set_inode(&mut self, inode: Inode) {
93 self.inode = Some(inode);
94 }
95
96 pub fn set_type(&mut self, r#type: Kind) {
97 self.r#type = r#type;
98 }
99
100 pub fn set_creation_time(&mut self, time: Time) {
101 self.creation_time = time;
102 }
103
104 pub fn set_modification_time(&mut self, time: Time) {
105 self.modification_time = time;
106 }
107
108 pub fn set_access_time(&mut self, time: Time) {
109 self.access_time = time;
110 }
111
112 pub fn set_permissions(&mut self, permissions: Permissions) {
113 self.permissions = permissions;
114 }
115
116 pub fn set_owner(&mut self, owner: UserIdentifier) {
117 self.user = owner;
118 }
119
120 pub fn set_group(&mut self, group: GroupIdentifier) {
121 self.group = group;
122 }
123}
124
125#[cfg(test)]
126mod tests {
127 use super::*;
128
129 fn create_test_metadata() -> Metadata {
130 let current_time = Time::new(1640995200);
131 let user = UserIdentifier::new(1000);
132 let group = GroupIdentifier::new(1000);
133
134 Metadata::get_default(Kind::File, current_time, user, group).unwrap()
135 }
136
137 #[test]
138 fn test_metadata_creation() {
139 let current_time = Time::new(1640995200);
140 let user = UserIdentifier::new(1000);
141 let group = GroupIdentifier::new(1000);
142
143 let metadata = Metadata::get_default(Kind::File, current_time, user, group);
144 assert!(metadata.is_some());
145
146 let metadata = metadata.unwrap();
147 assert_eq!(metadata.get_type(), Kind::File);
148 assert_eq!(metadata.get_creation_time(), current_time);
149 assert_eq!(metadata.get_modification_time(), current_time);
150 assert_eq!(metadata.get_access_time(), current_time);
151 assert_eq!(metadata.get_user(), user);
152 assert_eq!(metadata.get_group(), group);
153 assert!(metadata.get_inode().is_none());
154 }
155
156 #[test]
157 fn test_metadata_identifier() {
158 assert_eq!(Metadata::IDENTIFIER, 0x01);
159 }
160
161 #[test]
162 fn test_metadata_getters() {
163 let metadata = create_test_metadata();
164
165 assert!(metadata.get_inode().is_none());
167 assert_eq!(metadata.get_type(), Kind::File);
168 assert_eq!(metadata.get_creation_time().as_u64(), 1640995200);
169 assert_eq!(metadata.get_modification_time().as_u64(), 1640995200);
170 assert_eq!(metadata.get_access_time().as_u64(), 1640995200);
171 assert_eq!(metadata.get_user().as_u16(), 1000);
172 assert_eq!(metadata.get_group().as_u16(), 1000);
173 }
174
175 #[test]
176 fn test_metadata_setters() {
177 let mut metadata = create_test_metadata();
178
179 let inode = Inode::new(42);
181 metadata.set_inode(inode);
182 assert_eq!(metadata.get_inode(), Some(inode));
183
184 metadata.set_type(Kind::Directory);
186 assert_eq!(metadata.get_type(), Kind::Directory);
187
188 let new_time = Time::new(1641081600);
190 metadata.set_creation_time(new_time);
191 metadata.set_modification_time(new_time);
192 metadata.set_access_time(new_time);
193
194 assert_eq!(metadata.get_creation_time(), new_time);
195 assert_eq!(metadata.get_modification_time(), new_time);
196 assert_eq!(metadata.get_access_time(), new_time);
197
198 let new_user = UserIdentifier::new(2000);
200 let new_group = GroupIdentifier::new(2000);
201
202 metadata.set_owner(new_user);
203 metadata.set_group(new_group);
204
205 assert_eq!(metadata.get_user(), new_user);
206 assert_eq!(metadata.get_group(), new_group);
207 }
208
209 #[test]
210 fn test_metadata_permissions() {
211 let metadata = create_test_metadata();
212 let _permissions = metadata.get_permissions();
213
214 let mut metadata = metadata;
216 let new_permissions = Permissions::new_default(Kind::Directory);
217 metadata.set_permissions(new_permissions);
218
219 assert_eq!(metadata.get_permissions(), new_permissions);
220 }
221
222 #[test]
223 fn test_metadata_clone() {
224 let original = create_test_metadata();
225 let cloned = original.clone();
226
227 assert_eq!(original, cloned);
228 assert_eq!(original.get_type(), cloned.get_type());
229 assert_eq!(original.get_creation_time(), cloned.get_creation_time());
230 assert_eq!(original.get_user(), cloned.get_user());
231 assert_eq!(original.get_group(), cloned.get_group());
232 }
233
234 #[test]
235 fn test_metadata_equality() {
236 let metadata1 = create_test_metadata();
237 let metadata2 = create_test_metadata();
238
239 assert_eq!(metadata1, metadata2);
240
241 let mut metadata3 = create_test_metadata();
243 metadata3.set_type(Kind::Directory);
244
245 assert_ne!(metadata1, metadata3);
246 }
247
248 #[test]
249 fn test_metadata_debug() {
250 let metadata = create_test_metadata();
251 let debug_str = alloc::format!("{metadata:?}");
252
253 assert!(debug_str.contains("Metadata_type"));
254 assert!(debug_str.contains("File"));
255 assert!(debug_str.contains("1640995200"));
256 }
257
258 #[test]
259 fn test_metadata_different_types() {
260 let current_time = Time::new(1640995200);
261 let user = UserIdentifier::new(1000);
262 let group = GroupIdentifier::new(1000);
263
264 let file_metadata = Metadata::get_default(Kind::File, current_time, user, group).unwrap();
266 let dir_metadata =
267 Metadata::get_default(Kind::Directory, current_time, user, group).unwrap();
268 let symlink_metadata =
269 Metadata::get_default(Kind::SymbolicLink, current_time, user, group).unwrap();
270
271 assert_eq!(file_metadata.get_type(), Kind::File);
272 assert_eq!(dir_metadata.get_type(), Kind::Directory);
273 assert_eq!(symlink_metadata.get_type(), Kind::SymbolicLink);
274
275 assert_ne!(
277 file_metadata.get_permissions(),
278 dir_metadata.get_permissions()
279 );
280 }
281
282 #[test]
283 fn test_metadata_inode_operations() {
284 let mut metadata = create_test_metadata();
285
286 assert!(metadata.get_inode().is_none());
288
289 let inode1 = Inode::new(42);
291 metadata.set_inode(inode1);
292 assert_eq!(metadata.get_inode(), Some(inode1));
293
294 let inode2 = Inode::new(84);
296 metadata.set_inode(inode2);
297 assert_eq!(metadata.get_inode(), Some(inode2));
298 assert_ne!(metadata.get_inode(), Some(inode1));
299 }
300
301 #[test]
302 fn test_metadata_time_updates() {
303 let mut metadata = create_test_metadata();
304
305 let initial_time = metadata.get_creation_time();
306 let new_time = Time::new(initial_time.as_u64() + 3600); metadata.set_creation_time(new_time);
310 assert_eq!(metadata.get_creation_time(), new_time);
311 assert_eq!(metadata.get_modification_time(), initial_time); assert_eq!(metadata.get_access_time(), initial_time); metadata.set_modification_time(new_time);
315 assert_eq!(metadata.get_modification_time(), new_time);
316 assert_eq!(metadata.get_access_time(), initial_time); metadata.set_access_time(new_time);
319 assert_eq!(metadata.get_access_time(), new_time);
320 }
321
322 #[test]
323 fn test_metadata_user_group_operations() {
324 let mut metadata = create_test_metadata();
325
326 let _initial_user = metadata.get_user();
327 let initial_group = metadata.get_group();
328
329 let new_user = UserIdentifier::new(5000);
330 let new_group = GroupIdentifier::new(5000);
331
332 metadata.set_owner(new_user);
334 assert_eq!(metadata.get_user(), new_user);
335 assert_eq!(metadata.get_group(), initial_group); metadata.set_group(new_group);
339 assert_eq!(metadata.get_group(), new_group);
340 assert_eq!(metadata.get_user(), new_user); }
342
343 #[test]
344 fn test_metadata_comprehensive_modification() {
345 let mut metadata = create_test_metadata();
346
347 let new_inode = Inode::new(999);
349 let new_type = Kind::Socket;
350 let new_time = Time::new(2000000000);
351 let new_user = UserIdentifier::new(9999);
352 let new_group = GroupIdentifier::new(9999);
353 let new_permissions = Permissions::new_default(Kind::Socket);
354
355 metadata.set_inode(new_inode);
356 metadata.set_type(new_type);
357 metadata.set_creation_time(new_time);
358 metadata.set_modification_time(new_time);
359 metadata.set_access_time(new_time);
360 metadata.set_owner(new_user);
361 metadata.set_group(new_group);
362 metadata.set_permissions(new_permissions);
363
364 assert_eq!(metadata.get_inode(), Some(new_inode));
366 assert_eq!(metadata.get_type(), new_type);
367 assert_eq!(metadata.get_creation_time(), new_time);
368 assert_eq!(metadata.get_modification_time(), new_time);
369 assert_eq!(metadata.get_access_time(), new_time);
370 assert_eq!(metadata.get_user(), new_user);
371 assert_eq!(metadata.get_group(), new_group);
372 assert_eq!(metadata.get_permissions(), new_permissions);
373 }
374}