Skip to content

Commit bd3baa1

Browse files
committed
Add Type enum for matching on file type
1 parent 2bfcc7e commit bd3baa1

File tree

1 file changed

+60
-18
lines changed

1 file changed

+60
-18
lines changed

src/lib.rs

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,66 @@ fn type_bits(mode: u32) -> u32 {
4343
(mode >> 12) & 0o17
4444
}
4545

46+
/// The different types of files known to this library
47+
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
48+
pub enum Type {
49+
File,
50+
Dir,
51+
Symlink,
52+
Socket,
53+
Fifo,
54+
BlockDevice,
55+
CharDevice,
56+
/// Removed file in union filesystems
57+
Whiteout,
58+
Unknown,
59+
}
60+
61+
impl Type {
62+
/// Parse type from mode
63+
///
64+
/// ```
65+
/// assert_eq!(unix_mode::Type::from(0o0100640), unix_mode::Type::File);
66+
/// ```
67+
pub fn from(mode: u32) -> Type {
68+
use Type::*;
69+
match type_bits(mode) {
70+
0o001 => Fifo,
71+
0o002 => CharDevice,
72+
0o004 => Dir,
73+
0o006 => BlockDevice,
74+
0o010 => File,
75+
0o012 => Symlink,
76+
0o014 => Socket,
77+
0o016 => Whiteout,
78+
_ => Unknown,
79+
}
80+
}
81+
82+
fn short(self) -> char {
83+
use Type::*;
84+
match self {
85+
Fifo => 'p',
86+
CharDevice => 'c',
87+
Dir => 'd',
88+
BlockDevice => 'b',
89+
File => '-',
90+
Symlink => 'l',
91+
Socket => 's',
92+
Whiteout => 'w',
93+
Unknown => '?',
94+
}
95+
}
96+
}
97+
4698
/// Returns true if this mode represents a regular file.
4799
///
48100
/// ```
49101
/// assert_eq!(unix_mode::is_file(0o0041777), false);
50102
/// assert_eq!(unix_mode::is_file(0o0100640), true);
51103
/// ```
52104
pub fn is_file(mode: u32) -> bool {
53-
type_bits(mode) == 0o010
105+
Type::from(mode) == Type::File
54106
}
55107

56108
/// Returns true if this mode represents a directory.
@@ -60,7 +112,7 @@ pub fn is_file(mode: u32) -> bool {
60112
/// assert_eq!(unix_mode::is_dir(0o0100640), false);
61113
/// ```
62114
pub fn is_dir(mode: u32) -> bool {
63-
type_bits(mode) == 0o004
115+
Type::from(mode) == Type::Dir
64116
}
65117

66118
/// Returns true if this mode represents a symlink.
@@ -70,27 +122,27 @@ pub fn is_dir(mode: u32) -> bool {
70122
/// assert_eq!(unix_mode::is_symlink(0o0120755), true);
71123
/// ```
72124
pub fn is_symlink(mode: u32) -> bool {
73-
type_bits(mode) == 0o012
125+
Type::from(mode) == Type::Symlink
74126
}
75127

76128
/// Returns true if this mode represents a fifo, also known as a named pipe.
77129
pub fn is_fifo(mode: u32) -> bool {
78-
type_bits(mode) == 0o001
130+
Type::from(mode) == Type::Fifo
79131
}
80132

81133
/// Returns true if this mode represents a character device.
82134
pub fn is_char_device(mode: u32) -> bool {
83-
type_bits(mode) == 0o002
135+
Type::from(mode) == Type::CharDevice
84136
}
85137

86138
/// Returns true if this mode represents a block device.
87139
pub fn is_block_device(mode: u32) -> bool {
88-
type_bits(mode) == 0o006
140+
Type::from(mode) == Type::BlockDevice
89141
}
90142

91143
/// Returns true if this mode represents a Unix-domain socket.
92144
pub fn is_socket(mode: u32) -> bool {
93-
type_bits(mode) == 0o014
145+
Type::from(mode) == Type::Socket
94146
}
95147

96148
/// Returns true if the set-user-ID bit is set
@@ -144,17 +196,7 @@ pub fn to_string(mode: u32) -> String {
144196
}
145197

146198
let mut s = String::with_capacity(10);
147-
s.push(match (mode >> 12) & 0o17 {
148-
0o001 => 'p', // pipe/fifo
149-
0o002 => 'c', // character dev
150-
0o004 => 'd', // directory
151-
0o006 => 'b', // block dev
152-
0o010 => '-', // regular file
153-
0o012 => 'l', // link
154-
0o014 => 's', // socket
155-
0o016 => 'w', // whiteout
156-
_ => '?', // unknown
157-
});
199+
s.push(Type::from(mode).short());
158200
let setuid = is_setuid(mode);
159201
let setgid = is_setgid(mode);
160202
let sticky = is_sticky(mode);

0 commit comments

Comments
 (0)