nuts_archive/entry/
mode.rs1use nuts_bytes::{FromBytes, ToBytes};
24
25#[cfg(test)]
26mod tests;
27
28const MASK_TYPE: u16 = 0x0600;
29const TYPE_FILE: u16 = 0x0000;
30const TYPE_DIR: u16 = 0x0200;
31const TYPE_SYMLINK: u16 = 0x0400;
32
33const MASK_USR_R: u16 = 0x0001;
34const MASK_USR_W: u16 = 0x0002;
35const MASK_USR_X: u16 = 0x0004;
36const MASK_GRP_R: u16 = 0x0008;
37const MASK_GRP_W: u16 = 0x0010;
38const MASK_GRP_X: u16 = 0x0020;
39const MASK_OTH_R: u16 = 0x0040;
40const MASK_OTH_W: u16 = 0x0080;
41const MASK_OTH_X: u16 = 0x0100;
42
43const DEFAULT_ACCESS_RIGHTS: u16 =
44 MASK_USR_R | MASK_USR_W | MASK_USR_X | MASK_GRP_R | MASK_GRP_X | MASK_OTH_R | MASK_OTH_X;
45
46#[derive(Clone, Copy, PartialEq)]
47pub enum Group {
48 User,
49 Group,
50 Other,
51}
52
53#[derive(Clone, Copy, Debug, FromBytes, ToBytes)]
55pub(crate) struct Mode(u16);
56
57impl Mode {
58 pub fn file() -> Mode {
59 Mode(TYPE_FILE | DEFAULT_ACCESS_RIGHTS)
60 }
61
62 pub fn directory() -> Mode {
63 Mode(TYPE_DIR | DEFAULT_ACCESS_RIGHTS)
64 }
65
66 pub fn symlink() -> Mode {
67 Mode(TYPE_SYMLINK | DEFAULT_ACCESS_RIGHTS)
68 }
69
70 pub fn is_file(&self) -> bool {
72 self.0 & MASK_TYPE == TYPE_FILE
73 }
74
75 pub fn is_directory(&self) -> bool {
77 self.0 & MASK_TYPE == TYPE_DIR
78 }
79
80 pub fn is_symlink(&self) -> bool {
82 self.0 & MASK_TYPE == TYPE_SYMLINK
83 }
84
85 pub fn can_read(&self, group: Group) -> bool {
87 self.0 & Self::read_mask(group) > 0
88 }
89
90 pub fn set_readable(&mut self, group: Group, readable: bool) {
95 self.update_mask(readable, Self::read_mask(group));
96 }
97
98 pub fn can_write(&self, group: Group) -> bool {
100 self.0 & Self::write_mask(group) > 0
101 }
102
103 pub fn set_writable(&mut self, group: Group, writable: bool) {
108 self.update_mask(writable, Self::write_mask(group));
109 }
110
111 pub fn can_execute(&self, group: Group) -> bool {
113 self.0 & Self::execute_mask(group) > 0
114 }
115
116 pub fn set_executable(&mut self, group: Group, executable: bool) {
121 self.update_mask(executable, Self::execute_mask(group));
122 }
123
124 fn read_mask(group: Group) -> u16 {
125 match group {
126 Group::User => MASK_USR_R,
127 Group::Group => MASK_GRP_R,
128 Group::Other => MASK_OTH_R,
129 }
130 }
131
132 fn write_mask(group: Group) -> u16 {
133 match group {
134 Group::User => MASK_USR_W,
135 Group::Group => MASK_GRP_W,
136 Group::Other => MASK_OTH_W,
137 }
138 }
139
140 fn execute_mask(group: Group) -> u16 {
141 match group {
142 Group::User => MASK_USR_X,
143 Group::Group => MASK_GRP_X,
144 Group::Other => MASK_OTH_X,
145 }
146 }
147
148 fn update_mask(&mut self, enable: bool, mask: u16) {
149 if enable {
150 self.0 |= mask;
151 } else {
152 self.0 &= !mask;
153 }
154 }
155}