use crate::error::Result;
use sysinfo::Disks;
#[derive(Debug, Clone)]
pub struct DiskInfo {
pub mount_point: String,
pub filesystem: String,
pub total_bytes: u64,
pub available_bytes: u64,
pub used_bytes: u64,
pub is_removable: bool,
pub name: String,
}
pub fn collect() -> Result<Vec<DiskInfo>> {
let disks = Disks::new_with_refreshed_list();
let mut result = Vec::new();
for disk in disks.list() {
let total = disk.total_space();
let available = disk.available_space();
let used = total.saturating_sub(available);
if total == 0 {
continue;
}
result.push(DiskInfo {
mount_point: disk.mount_point().to_string_lossy().to_string(),
filesystem: disk.file_system().to_string_lossy().to_string(),
total_bytes: total,
available_bytes: available,
used_bytes: used,
is_removable: disk.is_removable(),
name: disk.name().to_string_lossy().to_string(),
});
}
Ok(result)
}
impl DiskInfo {
pub fn usage_percent(&self) -> f32 {
if self.total_bytes == 0 {
0.0
} else {
(self.used_bytes as f64 / self.total_bytes as f64 * 100.0) as f32
}
}
fn format_bytes(bytes: u64) -> String {
crate::format_bytes(bytes)
}
pub fn total_formatted(&self) -> String {
Self::format_bytes(self.total_bytes)
}
pub fn available_formatted(&self) -> String {
Self::format_bytes(self.available_bytes)
}
pub fn used_formatted(&self) -> String {
Self::format_bytes(self.used_bytes)
}
pub fn usage_string(&self) -> String {
format!(
"{} / {} ({:.1}%)",
self.used_formatted(),
self.total_formatted(),
self.usage_percent()
)
}
pub fn display_name(&self) -> String {
if self.name.is_empty() {
self.mount_point.clone()
} else {
format!("{} ({})", self.name, self.mount_point)
}
}
}