Skip to main content

simply_fuse/
attrs.rs

1use std::time::Duration;
2
3use typed_builder::TypedBuilder;
4
5#[derive(Copy, Clone, Debug, TypedBuilder)]
6#[builder(field_defaults(default, setter(into)))]
7pub struct FileAttributes {
8    #[builder(!default, setter(!strip_option))]
9    mode: u32,
10    #[builder(default = 4096, setter(!strip_option))]
11    size: u64,
12    nlink: u32,
13
14    uid: u32,
15    gid: u32,
16
17    rdev: u32,
18    blksize: u32,
19    blocks: u64,
20
21    atime: Duration,
22    mtime: Duration,
23    ctime: Duration,
24
25    #[builder(default = Duration::from_secs(1))]
26    ttl: Duration,
27}
28
29impl FileAttributes {
30    pub fn mode(&self) -> u32 {
31        self.mode
32    }
33
34    pub fn size(&self) -> u64 {
35        self.size
36    }
37
38    pub fn nlink(&self) -> u32 {
39        self.nlink
40    }
41
42    pub fn uid(&self) -> u32 {
43        self.uid
44    }
45
46    pub fn gid(&self) -> u32 {
47        self.gid
48    }
49
50    pub fn rdev(&self) -> u32 {
51        self.rdev
52    }
53
54    pub fn blksize(&self) -> u32 {
55        self.blksize
56    }
57
58    pub fn blocks(&self) -> u64 {
59        self.blocks
60    }
61
62    pub fn atime(&self) -> Duration {
63        self.atime
64    }
65
66    pub fn mtime(&self) -> Duration {
67        self.mtime
68    }
69
70    pub fn ctime(&self) -> Duration {
71        self.ctime
72    }
73
74    /// # Note
75    /// `ttl` means `time to live`
76    /// This is **not** time to live, such as you'd go live on Twitch. It means time to live,
77    /// as in the remaining time you have left alive. I spent way too long misunderstanding
78    /// that.
79    pub fn ttl(&self) -> Duration {
80        self.ttl
81    }
82
83    pub fn set_mode(&mut self, mode: u32) {
84        self.mode = mode;
85    }
86
87    pub fn set_size(&mut self, size: u64) {
88        self.size = size;
89    }
90
91    pub fn set_nlink(&mut self, nlink: u32) {
92        self.nlink = nlink;
93    }
94
95    pub fn set_uid(&mut self, uid: u32) {
96        self.uid = uid;
97    }
98
99    pub fn set_gid(&mut self, gid: u32) {
100        self.gid = gid;
101    }
102
103    pub fn set_rdev(&mut self, rdev: u32) {
104        self.rdev = rdev;
105    }
106
107    pub fn set_blksize(&mut self, blksize: u32) {
108        self.blksize = blksize;
109    }
110    pub fn set_blocks(&mut self, blocks: u64) {
111        self.blocks = blocks;
112    }
113
114    pub fn set_atime(&mut self, atime: Duration) {
115        self.atime = atime;
116    }
117    pub fn set_mtime(&mut self, mtime: Duration) {
118        self.mtime = mtime;
119    }
120    pub fn set_ctime(&mut self, ctime: Duration) {
121        self.ctime = ctime;
122    }
123    pub fn set_ttl(&mut self, ttl: Duration) {
124        self.ttl = ttl;
125    }
126
127    #[deny(unused_variables)]
128    pub fn apply_attrs(&mut self, attrs: SetFileAttributes) {
129        // Here's a cool trick: By denying unused variables for this function and unpacking the
130        // struct below, this function will fail to compile if we update SetFileAttributes without
131        // modifying this function. Sure, there's reasons we might want to do that in the future,
132        // but we also want to make sure we always modify these variables
133        let SetFileAttributes {
134            mode,
135            size,
136            uid,
137            gid,
138            atime,
139            mtime,
140            ctime,
141        } = attrs;
142
143        // TODO convert this to macro_rules! maybe
144        macro_rules! copy_attr {
145            () => {};
146
147            ($attr:ident) => {
148                if let Some(attr) = $attr {
149                    self.$attr = attr;
150                }
151            };
152
153            ($attr:ident, $($tail:tt)*) => {
154                copy_attr!($attr);
155                copy_attr!($($tail)*);
156            };
157        }
158
159        copy_attr!(mode, size, uid, gid, atime, mtime, ctime);
160    }
161}
162
163#[derive(Copy, Clone, Debug, TypedBuilder)]
164pub struct SetFileAttributes {
165    mode: Option<u32>,
166    size: Option<u64>,
167
168    uid: Option<u32>,
169    gid: Option<u32>,
170
171    atime: Option<Duration>,
172    mtime: Option<Duration>,
173    ctime: Option<Duration>,
174}
175
176impl SetFileAttributes {
177    pub fn mode(&self) -> Option<u32> {
178        self.mode
179    }
180
181    pub fn size(&self) -> Option<u64> {
182        self.size
183    }
184
185    pub fn uid(&self) -> Option<u32> {
186        self.uid
187    }
188
189    pub fn gid(&self) -> Option<u32> {
190        self.gid
191    }
192
193    pub fn atime(&self) -> Option<Duration> {
194        self.atime
195    }
196
197    pub fn mtime(&self) -> Option<Duration> {
198        self.mtime
199    }
200
201    pub fn ctime(&self) -> Option<Duration> {
202        self.ctime
203    }
204}