rune/dired.rs
1#[cfg(unix)]
2use crate::core::object::TRUE;
3use crate::core::{
4 gc::Context,
5 object::{NIL, Object, OptionalFlag},
6};
7#[cfg(unix)]
8use rune_core::macros::list;
9use rune_macros::defun;
10use std::path::Path;
11
12#[defun]
13fn file_attributes<'ob>(filename: &str, _id_format: OptionalFlag, cx: &'ob Context) -> Object<'ob> {
14 let file = Path::new(filename);
15 if file.exists() { metadata_attributes(file, cx) } else { NIL }
16}
17
18#[cfg(unix)]
19fn metadata_attributes<'ob>(file: &Path, cx: &'ob Context) -> Object<'ob> {
20 use std::os::unix::fs::MetadataExt;
21 let metadata = &file.metadata().unwrap();
22
23 // 0. t for directory, string (name linked to) for symbolic link, or nil.
24 let file_type = get_file_type(file, cx);
25 // 1. Number of hardlinks to file.
26 let links = metadata.nlink();
27 // 2. File uid as a string or (if ID-FORMAT is integer or a string value
28 // cannot be looked up) as an integer.
29 let uid = metadata.uid();
30 // 3. File gid, likewise.
31 let gid = metadata.gid();
32 // 4. Last access time, in the style of current-time.
33 // (See a note below about access time on FAT-based filesystems.)
34 let atime = metadata.atime();
35 // 5. Last modification time, likewise. This is the time of the last
36 // change to the file's contents.
37 let mtime = metadata.mtime();
38 // 6. Last status change time, likewise. This is the time of last change
39 // to the file's attributes: owner and group, access mode bits, etc.
40 let ctime = metadata.ctime();
41 // 7. Size in bytes, as an integer.
42 let size = metadata.size();
43 // 8. File modes, as a string of ten letters or dashes as in ls -l.
44 let mode = metadata.mode();
45 // 9. An unspecified value, present only for backward compatibility.
46 // 10. inode number, as a nonnegative integer.
47 let inode = metadata.ino();
48 // 11. Filesystem device identifier, as an integer or a cons cell of integers.
49 let dev = metadata.dev();
50 list![file_type, links, uid, gid, atime, mtime, ctime, size, mode, TRUE, inode, dev; cx]
51}
52
53#[cfg(windows)]
54fn metadata_attributes<'ob>(_file: &Path, _cx: &'ob Context) -> Object<'ob> {
55 // use std::os::windows::fs::MetadataExt;
56 // let metadata = &file.metadata().unwrap();
57
58 // 0. t for directory, string (name linked to) for symbolic link, or nil.
59 // let file_type = get_file_type(file, cx);
60 // TODO: implement the rest of the attributes
61 // 1. Number of hardlinks to file.
62 // 2. File uid as a string or (if ID-FORMAT is integer or a string value
63 // cannot be looked up) as an integer.
64 // 3. File gid, likewise.
65 // 4. Last access time, in the style of current-time.
66 // (See a note below about access time on FAT-based filesystems.)
67 // 5. Last modification time, likewise. This is the time of the last
68 // change to the file's contents.
69 // 6. Last status change time, likewise. This is the time of last change
70 // to the file's attributes: owner and group, access mode bits, etc.
71 // 7. Size in bytes, as an integer.
72 // 8. File modes, as a string of ten letters or dashes as in ls -l.
73 // 9. An unspecified value, present only for backward compatibility.
74 // 10. inode number, as a nonnegative integer.
75 // 11. Filesystem device identifier, as an integer or a cons cell of integers.
76 panic!("file-attributes are not yet implemented for non-unix systems");
77}
78
79#[cfg(unix)]
80fn get_file_type<'ob>(file: &Path, cx: &'ob Context) -> Object<'ob> {
81 if file.is_dir() {
82 TRUE
83 } else if file.is_symlink() {
84 let target = file.read_link().unwrap();
85 cx.add(target.to_str().unwrap())
86 } else {
87 NIL
88 }
89}