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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
use systemstat::{System, Platform};
use systemstat::data::Filesystem;
use std::path::{Path, PathBuf, Component};
use std::collections::HashMap;
use crate::fail::{HResult, ErrorLog};
#[derive(Debug,Clone)]
pub struct FsStat {
pub stats: HashMap<PathBuf, Filesystem>
}
impl FsStat {
pub fn new() -> HResult<FsStat> {
let mut stats = FsStat { stats: HashMap::new() };
stats.refresh().log();
Ok(stats)
}
pub fn refresh(&mut self) -> HResult<()> {
let sys = System::new();
let mounts = sys.mounts()?;
let stats = mounts.into_iter()
.fold(HashMap::new(), |mut stats, mount: Filesystem| {
let path = PathBuf::from(&mount.fs_mounted_on);
stats.insert(path, mount);
stats
});
self.stats = stats;
Ok(())
}
pub fn find_fs(&self, path: &Path) -> HResult<&Filesystem> {
let candidates = self
.stats
.keys()
.filter(|mount_point| path.starts_with(&mount_point))
.collect::<Vec<&PathBuf>>();
let deepest_match = candidates.iter()
.fold(PathBuf::new(), |mut deepest, path| {
let curren_path_len = deepest.components().count();
let candidate_path_len = path.components().count();
if candidate_path_len > curren_path_len {
deepest = path.to_path_buf();
}
deepest
});
let fs = self.stats.get(&deepest_match)?;
Ok(fs)
}
}
pub trait FsExt {
fn get_dev(&self) -> String;
fn get_total(&self) -> String;
fn get_free(&self) -> String;
}
impl FsExt for Filesystem {
fn get_dev(&self) -> String {
let path = PathBuf::from(&self.fs_mounted_from);
let dev = match path.components().last() {
Some(Component::Normal(dev)) => dev.to_string_lossy().to_string(),
_ => "FS".to_string()
};
dev
}
fn get_total(&self) -> String {
self.total.to_string(false)
}
fn get_free(&self) -> String {
self.avail.to_string(false)
}
}
|