1use std::{fmt::Debug, os::unix::fs::PermissionsExt};
2
3#[cfg(unix)]
4use libc::mode_t;
5
6#[cfg(unix)]
7#[derive(Clone, PartialEq, Eq)]
8pub(crate) struct FilePermissions {
9 pub(crate) mode: mode_t,
10}
11
12impl FilePermissions {
13 fn readonly(&self) -> bool {
14 self.mode & 0o222 == 0
15 }
16
17 #[cfg(target_os = "linux")]
18 fn mode(&self) -> u32 {
19 self.mode
20 }
21
22 fn set_readonly(&mut self, readonly: bool) {
23 if readonly {
24 self.mode &= !0o222;
25 } else {
26 self.mode |= 0o222;
27 }
28 }
29
30 #[cfg(not(target_os = "linux"))]
31 fn mode(&self) -> u32 {
32 unimplemented!()
33 }
34}
35
36#[cfg(unix)]
38pub struct Permissions(pub(crate) FilePermissions);
39
40impl Permissions {
41 pub fn readonly(&self) -> bool {
43 self.0.readonly()
44 }
45
46 #[allow(unused)]
52 pub fn set_readonly(&mut self, readonly: bool) {
53 self.0.set_readonly(readonly)
54 }
55}
56
57impl PermissionsExt for Permissions {
58 fn mode(&self) -> u32 {
60 self.0.mode()
61 }
62
63 fn set_mode(&mut self, mode: u32) {
69 *self = Self::from_mode(mode);
70 }
71
72 fn from_mode(mode: u32) -> Self {
74 Self(FilePermissions {
75 mode: mode as mode_t,
76 })
77 }
78}
79
80impl Debug for Permissions {
81 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82 f.debug_struct("Permissions")
83 .field("readonly", &self.readonly())
84 .finish_non_exhaustive()
85 }
86}