1 // Stolen from https://github.com/Peltoche/lsd/blob/master/src/meta/permissions.rs 2 3 use serde::{Deserialize, Serialize}; 4 use std::fs::Metadata; 5 6 #[derive( 7 Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize, Hash, Default, 8 )] 9 pub struct Permissions { 10 pub user_read: bool, 11 pub user_write: bool, 12 pub user_execute: bool, 13 14 pub group_read: bool, 15 pub group_write: bool, 16 pub group_execute: bool, 17 18 pub other_read: bool, 19 pub other_write: bool, 20 pub other_execute: bool, 21 22 pub sticky: bool, 23 pub setgid: bool, 24 pub setuid: bool, 25 } 26 27 impl<'a> From<&'a Metadata> for Permissions { 28 #[cfg(unix)] from(meta: &Metadata) -> Self29 fn from(meta: &Metadata) -> Self { 30 use std::os::unix::fs::PermissionsExt; 31 32 let bits = meta.permissions().mode(); 33 let has_bit = |bit| bits & bit == bit; 34 35 Self { 36 user_read: has_bit(modes::USER_READ), 37 user_write: has_bit(modes::USER_WRITE), 38 user_execute: has_bit(modes::USER_EXECUTE), 39 40 group_read: has_bit(modes::GROUP_READ), 41 group_write: has_bit(modes::GROUP_WRITE), 42 group_execute: has_bit(modes::GROUP_EXECUTE), 43 44 other_read: has_bit(modes::OTHER_READ), 45 other_write: has_bit(modes::OTHER_WRITE), 46 other_execute: has_bit(modes::OTHER_EXECUTE), 47 48 sticky: has_bit(modes::STICKY), 49 setgid: has_bit(modes::SETGID), 50 setuid: has_bit(modes::SETUID), 51 } 52 } 53 54 #[cfg(windows)] from(_: &Metadata) -> Self55 fn from(_: &Metadata) -> Self { 56 panic!("Cannot get permissions from metadata on Windows") 57 } 58 } 59 60 // More readable aliases for the permission bits exposed by libc. 61 #[allow(trivial_numeric_casts)] 62 #[cfg(unix)] 63 mod modes { 64 pub type Mode = u32; 65 // The `libc::mode_t` type’s actual type varies, but the value returned 66 // from `metadata.permissions().mode()` is always `u32`. 67 68 pub const USER_READ: Mode = libc::S_IRUSR as Mode; 69 pub const USER_WRITE: Mode = libc::S_IWUSR as Mode; 70 pub const USER_EXECUTE: Mode = libc::S_IXUSR as Mode; 71 72 pub const GROUP_READ: Mode = libc::S_IRGRP as Mode; 73 pub const GROUP_WRITE: Mode = libc::S_IWGRP as Mode; 74 pub const GROUP_EXECUTE: Mode = libc::S_IXGRP as Mode; 75 76 pub const OTHER_READ: Mode = libc::S_IROTH as Mode; 77 pub const OTHER_WRITE: Mode = libc::S_IWOTH as Mode; 78 pub const OTHER_EXECUTE: Mode = libc::S_IXOTH as Mode; 79 80 pub const STICKY: Mode = libc::S_ISVTX as Mode; 81 pub const SETGID: Mode = libc::S_ISGID as Mode; 82 pub const SETUID: Mode = libc::S_ISUID as Mode; 83 } 84