Coverage Report

Created: 2025-11-28 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/sysinfo-0.33.1/src/common/disk.rs
Line
Count
Source
1
// Take a look at the license at the top of the repository in the LICENSE file.
2
3
use std::ffi::OsStr;
4
use std::fmt;
5
use std::path::Path;
6
7
use crate::common::impl_get_set::impl_get_set;
8
use crate::DiskUsage;
9
10
/// Struct containing a disk information.
11
///
12
/// ```no_run
13
/// use sysinfo::Disks;
14
///
15
/// let disks = Disks::new_with_refreshed_list();
16
/// for disk in disks.list() {
17
///     println!("{:?}: {:?}", disk.name(), disk.kind());
18
/// }
19
/// ```
20
pub struct Disk {
21
    pub(crate) inner: crate::DiskInner,
22
}
23
24
impl Disk {
25
    /// Returns the kind of disk.
26
    ///
27
    /// ```no_run
28
    /// use sysinfo::Disks;
29
    ///
30
    /// let disks = Disks::new_with_refreshed_list();
31
    /// for disk in disks.list() {
32
    ///     println!("[{:?}] {:?}", disk.name(), disk.kind());
33
    /// }
34
    /// ```
35
0
    pub fn kind(&self) -> DiskKind {
36
0
        self.inner.kind()
37
0
    }
38
39
    /// Returns the disk name.
40
    ///
41
    /// ```no_run
42
    /// use sysinfo::Disks;
43
    ///
44
    /// let disks = Disks::new_with_refreshed_list();
45
    /// for disk in disks.list() {
46
    ///     println!("{:?}", disk.name());
47
    /// }
48
    /// ```
49
0
    pub fn name(&self) -> &OsStr {
50
0
        self.inner.name()
51
0
    }
52
53
    /// Returns the file system used on this disk (so for example: `EXT4`, `NTFS`, etc...).
54
    ///
55
    /// ```no_run
56
    /// use sysinfo::Disks;
57
    ///
58
    /// let disks = Disks::new_with_refreshed_list();
59
    /// for disk in disks.list() {
60
    ///     println!("[{:?}] {:?}", disk.name(), disk.file_system());
61
    /// }
62
    /// ```
63
0
    pub fn file_system(&self) -> &OsStr {
64
0
        self.inner.file_system()
65
0
    }
66
67
    /// Returns the mount point of the disk (`/` for example).
68
    ///
69
    /// ```no_run
70
    /// use sysinfo::Disks;
71
    ///
72
    /// let disks = Disks::new_with_refreshed_list();
73
    /// for disk in disks.list() {
74
    ///     println!("[{:?}] {:?}", disk.name(), disk.mount_point());
75
    /// }
76
    /// ```
77
0
    pub fn mount_point(&self) -> &Path {
78
0
        self.inner.mount_point()
79
0
    }
80
81
    /// Returns the total disk size, in bytes.
82
    ///
83
    /// ```no_run
84
    /// use sysinfo::Disks;
85
    ///
86
    /// let disks = Disks::new_with_refreshed_list();
87
    /// for disk in disks.list() {
88
    ///     println!("[{:?}] {}B", disk.name(), disk.total_space());
89
    /// }
90
    /// ```
91
0
    pub fn total_space(&self) -> u64 {
92
0
        self.inner.total_space()
93
0
    }
94
95
    /// Returns the available disk size, in bytes.
96
    ///
97
    /// ```no_run
98
    /// use sysinfo::Disks;
99
    ///
100
    /// let disks = Disks::new_with_refreshed_list();
101
    /// for disk in disks.list() {
102
    ///     println!("[{:?}] {}B", disk.name(), disk.available_space());
103
    /// }
104
    /// ```
105
0
    pub fn available_space(&self) -> u64 {
106
0
        self.inner.available_space()
107
0
    }
108
109
    /// Returns `true` if the disk is removable.
110
    ///
111
    /// ```no_run
112
    /// use sysinfo::Disks;
113
    ///
114
    /// let disks = Disks::new_with_refreshed_list();
115
    /// for disk in disks.list() {
116
    ///     println!("[{:?}] {}", disk.name(), disk.is_removable());
117
    /// }
118
    /// ```
119
0
    pub fn is_removable(&self) -> bool {
120
0
        self.inner.is_removable()
121
0
    }
122
123
    /// Returns `true` if the disk is read-only.
124
    ///
125
    /// ```no_run
126
    /// use sysinfo::Disks;
127
    ///
128
    /// let disks = Disks::new_with_refreshed_list();
129
    /// for disk in disks.list() {
130
    ///     println!("[{:?}] is read-only: {}", disk.name(), disk.is_read_only());
131
    /// }
132
    /// ```
133
0
    pub fn is_read_only(&self) -> bool {
134
0
        self.inner.is_read_only()
135
0
    }
136
137
    /// Updates the disk' information with everything loaded.
138
    ///
139
    /// Equivalent to <code>[Disk::refresh_specifics]\([DiskRefreshKind::everything]\())</code>.
140
    ///
141
    /// ```no_run
142
    /// use sysinfo::Disks;
143
    ///
144
    /// let mut disks = Disks::new_with_refreshed_list();
145
    /// for disk in disks.list_mut() {
146
    ///     disk.refresh();
147
    /// }
148
    /// ```
149
0
    pub fn refresh(&mut self) -> bool {
150
0
        self.refresh_specifics(DiskRefreshKind::everything())
151
0
    }
152
153
    /// Updates the disk's information corresponding to the given [`DiskRefreshKind`].
154
    ///
155
    /// ```no_run
156
    /// use sysinfo::{Disks, DiskRefreshKind};
157
    ///
158
    /// let mut disks = Disks::new_with_refreshed_list();
159
    /// for disk in disks.list_mut() {
160
    ///     disk.refresh_specifics(DiskRefreshKind::nothing());
161
    /// }
162
    /// ```
163
0
    pub fn refresh_specifics(&mut self, refreshes: DiskRefreshKind) -> bool {
164
0
        self.inner.refresh_specifics(refreshes)
165
0
    }
166
167
    /// Returns number of bytes read and written by the disk
168
    ///
169
    /// ```no_run
170
    /// use sysinfo::Disks;
171
    ///
172
    /// let disks = Disks::new_with_refreshed_list();
173
    /// for disk in disks.list() {
174
    ///     println!("[{:?}] disk usage: {:?}", disk.name(), disk.usage());
175
    /// }
176
    /// ```
177
0
    pub fn usage(&self) -> DiskUsage {
178
0
        self.inner.usage()
179
0
    }
180
}
181
182
/// Disks interface.
183
///
184
/// ```no_run
185
/// use sysinfo::Disks;
186
///
187
/// let disks = Disks::new_with_refreshed_list();
188
/// for disk in disks.list() {
189
///     println!("{disk:?}");
190
/// }
191
/// ```
192
///
193
/// ⚠️ Note that tmpfs mounts are excluded by default under Linux.
194
/// To display tmpfs mount points, the `linux-tmpfs` feature must be enabled.
195
///
196
/// ⚠️ Note that network devices are excluded by default under Linux.
197
/// To display mount points using the CIFS and NFS protocols, the `linux-netdevs`
198
/// feature must be enabled. Note, however, that sysinfo may hang under certain
199
/// circumstances. For example, if a CIFS or NFS share has been mounted with
200
/// the _hard_ option, but the connection has an error, such as the share server has stopped.
201
pub struct Disks {
202
    inner: crate::DisksInner,
203
}
204
205
impl Default for Disks {
206
0
    fn default() -> Self {
207
0
        Self::new()
208
0
    }
209
}
210
211
impl From<Disks> for Vec<Disk> {
212
0
    fn from(disks: Disks) -> Vec<Disk> {
213
0
        disks.inner.into_vec()
214
0
    }
215
}
216
217
impl From<Vec<Disk>> for Disks {
218
0
    fn from(disks: Vec<Disk>) -> Self {
219
0
        Self {
220
0
            inner: crate::DisksInner::from_vec(disks),
221
0
        }
222
0
    }
223
}
224
225
impl<'a> IntoIterator for &'a Disks {
226
    type Item = &'a Disk;
227
    type IntoIter = std::slice::Iter<'a, Disk>;
228
229
0
    fn into_iter(self) -> Self::IntoIter {
230
0
        self.list().iter()
231
0
    }
232
}
233
234
impl<'a> IntoIterator for &'a mut Disks {
235
    type Item = &'a mut Disk;
236
    type IntoIter = std::slice::IterMut<'a, Disk>;
237
238
0
    fn into_iter(self) -> Self::IntoIter {
239
0
        self.list_mut().iter_mut()
240
0
    }
241
}
242
243
impl Disks {
244
    /// Creates a new empty [`Disks`][crate::Disks] type.
245
    ///
246
    /// If you want it to be filled directly, take a look at [`Disks::new_with_refreshed_list`].
247
    ///
248
    /// ```no_run
249
    /// use sysinfo::Disks;
250
    ///
251
    /// let mut disks = Disks::new();
252
    /// disks.refresh(false);
253
    /// for disk in disks.list() {
254
    ///     println!("{disk:?}");
255
    /// }
256
    /// ```
257
0
    pub fn new() -> Self {
258
0
        Self {
259
0
            inner: crate::DisksInner::new(),
260
0
        }
261
0
    }
262
263
    /// Creates a new [`Disks`][crate::Disks] type with the disk list loaded.
264
    ///
265
    /// Equivalent to <code>[Disks::new_with_refreshed_list_specifics]\([DiskRefreshKind::everything]\())</code>.
266
    ///
267
    /// ```no_run
268
    /// use sysinfo::Disks;
269
    ///
270
    /// let mut disks = Disks::new_with_refreshed_list();
271
    /// for disk in disks.list() {
272
    ///     println!("{disk:?}");
273
    /// }
274
    /// ```
275
0
    pub fn new_with_refreshed_list() -> Self {
276
0
        Self::new_with_refreshed_list_specifics(DiskRefreshKind::everything())
277
0
    }
278
279
    /// Creates a new [`Disks`][crate::Disks] type with the disk list loaded
280
    /// and refreshed according to the given [`DiskRefreshKind`].
281
    ///
282
    /// ```no_run
283
    /// use sysinfo::{Disks, DiskRefreshKind};
284
    ///
285
    /// let mut disks = Disks::new_with_refreshed_list_specifics(DiskRefreshKind::nothing());
286
    /// for disk in disks.list() {
287
    ///     println!("{disk:?}");
288
    /// }
289
    /// ```
290
0
    pub fn new_with_refreshed_list_specifics(refreshes: DiskRefreshKind) -> Self {
291
0
        let mut disks = Self::new();
292
0
        disks.refresh_specifics(false, refreshes);
293
0
        disks
294
0
    }
295
296
    /// Returns the disks list.
297
    ///
298
    /// ```no_run
299
    /// use sysinfo::Disks;
300
    ///
301
    /// let disks = Disks::new_with_refreshed_list();
302
    /// for disk in disks.list() {
303
    ///     println!("{disk:?}");
304
    /// }
305
    /// ```
306
0
    pub fn list(&self) -> &[Disk] {
307
0
        self.inner.list()
308
0
    }
309
310
    /// Returns the disks list.
311
    ///
312
    /// ```no_run
313
    /// use sysinfo::Disks;
314
    ///
315
    /// let mut disks = Disks::new_with_refreshed_list();
316
    /// for disk in disks.list_mut() {
317
    ///     disk.refresh();
318
    ///     println!("{disk:?}");
319
    /// }
320
    /// ```
321
0
    pub fn list_mut(&mut self) -> &mut [Disk] {
322
0
        self.inner.list_mut()
323
0
    }
324
325
    /// Refreshes the listed disks' information.
326
    ///
327
    /// Equivalent to <code>[Disks::refresh_specifics]\([DiskRefreshKind::everything]\())</code>.
328
0
    pub fn refresh(&mut self, remove_not_listed_disks: bool) {
329
0
        self.inner
330
0
            .refresh_specifics(remove_not_listed_disks, DiskRefreshKind::everything());
331
0
    }
332
333
    /// Refreshes the disks' information according to the given [`DiskRefreshKind`].
334
    ///
335
    /// ```no_run
336
    /// use sysinfo::Disks;
337
    ///
338
    /// let mut disks = Disks::new_with_refreshed_list();
339
    /// // We wait some time...?
340
    /// disks.refresh(true);
341
    /// ```
342
0
    pub fn refresh_specifics(&mut self, remove_not_listed_disks: bool, refreshes: DiskRefreshKind) {
343
0
        self.inner
344
0
            .refresh_specifics(remove_not_listed_disks, refreshes);
345
0
    }
346
}
347
348
impl std::ops::Deref for Disks {
349
    type Target = [Disk];
350
351
0
    fn deref(&self) -> &Self::Target {
352
0
        self.list()
353
0
    }
354
}
355
356
impl std::ops::DerefMut for Disks {
357
0
    fn deref_mut(&mut self) -> &mut Self::Target {
358
0
        self.list_mut()
359
0
    }
360
}
361
362
/// Enum containing the different supported kinds of disks.
363
///
364
/// This type is returned by [`Disk::kind`](`crate::Disk::kind`).
365
///
366
/// ```no_run
367
/// use sysinfo::Disks;
368
///
369
/// let disks = Disks::new_with_refreshed_list();
370
/// for disk in disks.list() {
371
///     println!("{:?}: {:?}", disk.name(), disk.kind());
372
/// }
373
/// ```
374
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
375
pub enum DiskKind {
376
    /// HDD type.
377
    HDD,
378
    /// SSD type.
379
    SSD,
380
    /// Unknown type.
381
    Unknown(isize),
382
}
383
384
impl fmt::Display for DiskKind {
385
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
386
0
        f.write_str(match *self {
387
0
            DiskKind::HDD => "HDD",
388
0
            DiskKind::SSD => "SSD",
389
0
            _ => "Unknown",
390
        })
391
0
    }
392
}
393
394
/// Used to determine what you want to refresh specifically on the [`Disk`] type.
395
///
396
/// * `kind` is about refreshing the [`Disk::kind`] information.
397
/// * `storage` is about refreshing the [`Disk::available_space`] and [`Disk::total_space`] information.
398
/// * `io_usage` is about refreshing the [`Disk::usage`] information.
399
///
400
/// ```no_run
401
/// use sysinfo::{Disks, DiskRefreshKind};
402
///
403
/// let mut disks = Disks::new_with_refreshed_list_specifics(DiskRefreshKind::everything());
404
///
405
/// for disk in disks.list() {
406
///     assert!(disk.total_space() != 0);
407
/// }
408
/// ```
409
#[derive(Clone, Copy, Debug, Default)]
410
pub struct DiskRefreshKind {
411
    kind: bool,
412
    storage: bool,
413
    io_usage: bool,
414
}
415
416
impl DiskRefreshKind {
417
    /// Creates a new `DiskRefreshKind` with every refresh set to false.
418
    ///
419
    /// ```
420
    /// use sysinfo::DiskRefreshKind;
421
    ///
422
    /// let r = DiskRefreshKind::nothing();
423
    ///
424
    /// assert_eq!(r.kind(), false);
425
    /// assert_eq!(r.storage(), false);
426
    /// assert_eq!(r.io_usage(), false);
427
    /// ```
428
0
    pub fn nothing() -> Self {
429
0
        Self::default()
430
0
    }
431
432
    /// Creates a new `DiskRefreshKind` with every refresh set to true.
433
    ///
434
    /// ```
435
    /// use sysinfo::DiskRefreshKind;
436
    ///
437
    /// let r = DiskRefreshKind::everything();
438
    ///
439
    /// assert_eq!(r.kind(), true);
440
    /// assert_eq!(r.storage(), true);
441
    /// assert_eq!(r.io_usage(), true);
442
    /// ```
443
0
    pub fn everything() -> Self {
444
0
        Self {
445
0
            kind: true,
446
0
            storage: true,
447
0
            io_usage: true,
448
0
        }
449
0
    }
450
451
    impl_get_set!(DiskRefreshKind, kind, with_kind, without_kind);
452
    impl_get_set!(DiskRefreshKind, storage, with_storage, without_storage);
453
    impl_get_set!(DiskRefreshKind, io_usage, with_io_usage, without_io_usage);
454
}