1use std::path::Path;
2use std::process::Command;
3
4use anyhow::Result;
5
6#[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
30pub 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 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}