1use std::{
2 fmt::Display,
3 path::{Path, PathBuf},
4};
5
6#[derive(Clone, PartialEq, Debug)]
8pub enum DiskKind {
9 SSD,
10 HDD,
11 NVME,
12 USB,
13}
14
15impl Display for DiskKind {
16 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17 match self {
18 DiskKind::SSD => write!(f, "SSD"),
19 DiskKind::HDD => write!(f, "HDD"),
20 DiskKind::NVME => write!(f, "NVME"),
21 DiskKind::USB => write!(f, "USB"),
22 }
23 }
24}
25
26pub fn disk_class(disk: impl AsRef<Path>) -> DiskKind {
28 let disk = disk.as_ref();
29 let drive = disk
30 .file_name()
31 .unwrap_or_default()
32 .to_str()
33 .unwrap_or_default();
34
35 if drive.starts_with("nvme") {
37 return DiskKind::NVME;
38 }
39
40 let link = PathBuf::from(format!("/sys/block/{drive}"));
42 if link.exists() {
43 let link = std::fs::read_link(link).unwrap_or_default();
44 if link.to_str().unwrap_or_default().contains("/usb") {
45 return DiskKind::USB;
46 }
47 }
48
49 let sys_class = PathBuf::from(format!("/sys/class/block/{drive}/queue/rotational"));
50
51 if sys_class.exists() {
53 let rotational = std::fs::read_to_string(sys_class).unwrap_or_default();
54 let rotational = rotational.trim();
55 if rotational == "1" {
56 return DiskKind::HDD;
57 }
58 }
59
60 DiskKind::SSD
61}