Skip to main content

diskforge_core/
disk.rs

1use std::path::Path;
2use std::process::Command;
3
4use anyhow::Result;
5
6/// Disk space info for a volume
7#[derive(Debug)]
8pub struct DiskInfo {
9    pub total: u64,
10    pub used: u64,
11    pub free: u64,
12}
13
14impl DiskInfo {
15    pub fn used_percent(&self) -> f64 {
16        if self.total == 0 {
17            return 0.0;
18        }
19        (self.used as f64 / self.total as f64) * 100.0
20    }
21
22    pub fn free_percent(&self) -> f64 {
23        if self.total == 0 {
24            return 0.0;
25        }
26        (self.free as f64 / self.total as f64) * 100.0
27    }
28}
29
30/// Get disk info for the volume containing the given path (macOS)
31pub fn get_disk_info(path: &Path) -> Result<DiskInfo> {
32    let output = Command::new("df").arg("-k").arg(path).output()?;
33
34    let stdout = String::from_utf8_lossy(&output.stdout);
35    let line = stdout
36        .lines()
37        .nth(1)
38        .ok_or_else(|| anyhow::anyhow!("unexpected df output"))?;
39
40    let parts: Vec<&str> = line.split_whitespace().collect();
41    if parts.len() < 4 {
42        anyhow::bail!("unexpected df output format");
43    }
44
45    // df -k outputs 1K blocks
46    let total = parts[1].parse::<u64>()? * 1024;
47    let used = parts[2].parse::<u64>()? * 1024;
48    let free = parts[3].parse::<u64>()? * 1024;
49
50    Ok(DiskInfo { total, used, free })
51}