1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
use {super::*, std::fs};
/// a "block device"
#[derive(Debug, Clone)]
pub struct Disk {
/// a name, like "sda", "sdc", "nvme0n1", etc.
pub name: String,
/// true for HDD, false for SSD, None for unknown.
/// This information isn't reliable for USB devices
pub rotational: Option<bool>,
/// whether the system thinks the media is removable.
/// Seems reliable.
pub removable: Option<bool>,
}
impl Disk {
pub fn new(name: String) -> Self {
let rotational = sys::read_file_as_bool(&format!("/sys/block/{}/queue/rotational", name));
let removable = sys::read_file_as_bool(&format!("/sys/block/{}/removable", name));
Self { name, rotational, removable }
}
/// a synthetic code trying to express the essence of the type of media,
/// an empty str being returned when information couldn't be gathered.
/// This code is for humans and may change in future minor versions.
pub fn disk_type(&self) -> &'static str {
match (self.removable, self.rotational) {
(Some(true), _) => "rem",
(Some(false), Some(true)) => "HDD",
(Some(false), Some(false)) => "SSD",
_ => "",
}
}
}
pub fn read_disks() -> Result<Vec<Disk>> {
Ok(fs::read_dir("/sys/block")?
.flatten()
.map(|e| e.file_name().into_string().unwrap())
.map(Disk::new)
.collect())
}