This commit is contained in:
Lutsai Aleksandr 2024-12-16 21:49:48 +03:00
parent ed9ca59452
commit 7f2ac0f3f3
5 changed files with 336 additions and 49 deletions

167
Cargo.lock generated
View file

@ -202,6 +202,26 @@ dependencies = [
"windows-targets", "windows-targets",
] ]
[[package]]
name = "bindgen"
version = "0.69.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
dependencies = [
"bitflags",
"cexpr",
"clang-sys",
"itertools 0.12.1",
"lazy_static",
"lazycell",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"syn",
]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.6.0" version = "2.6.0"
@ -272,6 +292,15 @@ dependencies = [
"shlex", "shlex",
] ]
[[package]]
name = "cexpr"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
dependencies = [
"nom",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.0"
@ -284,6 +313,17 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "clang-sys"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]] [[package]]
name = "compact_str" name = "compact_str"
version = "0.8.0" version = "0.8.0"
@ -330,6 +370,7 @@ checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"crossterm_winapi", "crossterm_winapi",
"futures-core",
"mio", "mio",
"parking_lot", "parking_lot",
"rustix", "rustix",
@ -596,6 +637,12 @@ version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "glob"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.15.2" version = "0.15.2"
@ -661,6 +708,15 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "itertools"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
dependencies = [
"either",
]
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.13.0" version = "0.13.0"
@ -682,12 +738,28 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.168" version = "0.2.168"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d"
[[package]]
name = "libloading"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
dependencies = [
"cfg-if",
"windows-targets",
]
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.4.14" version = "0.4.14"
@ -723,6 +795,17 @@ version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "loopdev-3"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90a97d7a5124296ee9124a815acdc3dc4a91f577b72812b3f1f99bb959b46e8d"
dependencies = [
"bindgen",
"errno",
"libc",
]
[[package]] [[package]]
name = "lru" name = "lru"
version = "0.12.5" version = "0.12.5"
@ -756,6 +839,12 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.8.0" version = "0.8.0"
@ -783,7 +872,9 @@ version = "0.1.0"
dependencies = [ dependencies = [
"crossterm", "crossterm",
"ratatui", "ratatui",
"sys-mount",
"tokio", "tokio",
"tokio-stream",
"udisks2", "udisks2",
] ]
@ -800,6 +891,16 @@ dependencies = [
"memoffset", "memoffset",
] ]
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]] [[package]]
name = "objc" name = "objc"
version = "0.2.7" version = "0.2.7"
@ -1015,7 +1116,7 @@ dependencies = [
"crossterm", "crossterm",
"indoc", "indoc",
"instability", "instability",
"itertools", "itertools 0.13.0",
"lru", "lru",
"paste", "paste",
"strum", "strum",
@ -1068,6 +1169,12 @@ version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.42" version = "0.38.42"
@ -1192,6 +1299,17 @@ version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "smart-default"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eb01866308440fc64d6c44d9e86c5cc17adfe33c4d6eed55da9145044d0ffc1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.5.8" version = "0.5.8"
@ -1247,6 +1365,20 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "sys-mount"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6acb8bb63826062d5a44b68298cf2e25b84bc151bc0c31c35a83b61f818682a"
dependencies = [
"bitflags",
"libc",
"loopdev-3",
"smart-default",
"thiserror",
"tracing",
]
[[package]] [[package]]
name = "temp-dir" name = "temp-dir"
version = "0.1.14" version = "0.1.14"
@ -1266,6 +1398,26 @@ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.42.0" version = "1.42.0"
@ -1295,6 +1447,17 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "tokio-stream"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047"
dependencies = [
"futures-core",
"pin-project-lite",
"tokio",
]
[[package]] [[package]]
name = "toml_datetime" name = "toml_datetime"
version = "0.6.8" version = "0.6.8"
@ -1391,7 +1554,7 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf"
dependencies = [ dependencies = [
"itertools", "itertools 0.13.0",
"unicode-segmentation", "unicode-segmentation",
"unicode-width 0.1.14", "unicode-width 0.1.14",
] ]

View file

@ -4,7 +4,9 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
crossterm = "0.28.1" crossterm = { version = "0.28.1", features = ["event-stream"]}
ratatui = "0.29.0" ratatui = "0.29.0"
sys-mount = "3.0.1"
tokio = {version = "1.42.0", features = ["full"]} tokio = {version = "1.42.0", features = ["full"]}
tokio-stream = "0.1.17"
udisks2 = "0.2.0" udisks2 = "0.2.0"

View file

@ -1,4 +1,5 @@
use std::{ use std::{
collections::HashMap,
ffi::{OsStr, OsString}, ffi::{OsStr, OsString},
os::unix::ffi::{OsStrExt, OsStringExt}, os::unix::ffi::{OsStrExt, OsStringExt},
sync::{Arc, Mutex}, sync::{Arc, Mutex},
@ -6,19 +7,20 @@ use std::{
use crate::mountpoints; use crate::mountpoints;
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct Block { pub struct Block {
pub id: String, pub object_path: String,
pub dev: String, pub dev: String,
pub label: String, pub label: String,
pub mount: Option<String>, pub mount: Option<String>,
pub fstype: String, pub fstype: String,
pub mounted: bool,
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct Drive { pub struct Drive {
pub id: String, pub id: String,
pub path: String, pub object_path: String,
pub model: String, pub model: String,
pub ejectable: bool, pub ejectable: bool,
pub blocks: Vec<Block>, pub blocks: Vec<Block>,
@ -44,14 +46,14 @@ pub async fn collect_drives_from_udisk() -> udisks2::Result<Vec<Drive>> {
let path = path.to_string(); let path = path.to_string();
if let Ok(drv) = i.drive().await { if let Ok(drv) = i.drive().await {
let drv = Drive { let drv = Drive {
path, object_path: path,
id: drv.id().await?, id: drv.id().await?,
model: drv.model().await?, model: drv.model().await?,
ejectable: drv.ejectable().await?, ejectable: drv.ejectable().await?,
blocks: Vec::new(), blocks: Vec::new(),
}; };
if let Some(d) = drives.iter_mut().find(|i| i.path == drv.path) { if let Some(d) = drives.iter_mut().find(|i| i.object_path == drv.object_path) {
d.model = drv.model; d.model = drv.model;
d.ejectable = drv.ejectable; d.ejectable = drv.ejectable;
d.id = drv.id; d.id = drv.id;
@ -61,7 +63,7 @@ pub async fn collect_drives_from_udisk() -> udisks2::Result<Vec<Drive>> {
} else if let Ok(blk) = i.block().await { } else if let Ok(blk) = i.block().await {
let drv_path = blk.drive().await?.to_string(); let drv_path = blk.drive().await?.to_string();
let block = Block { let block = Block {
id: blk.id().await?, object_path: path,
dev: String::from_utf8_lossy(&blk.device().await?) dev: String::from_utf8_lossy(&blk.device().await?)
.chars() .chars()
.filter(|c| c != &'\0') .filter(|c| c != &'\0')
@ -69,13 +71,14 @@ pub async fn collect_drives_from_udisk() -> udisks2::Result<Vec<Drive>> {
label: blk.id_label().await?, label: blk.id_label().await?,
mount: None, mount: None,
fstype: blk.id_type().await?, fstype: blk.id_type().await?,
mounted: false,
}; };
if let Some(d) = drives.iter_mut().find(|i| i.path == drv_path) { if let Some(d) = drives.iter_mut().find(|i| i.object_path == drv_path) {
d.blocks.push(block); d.blocks.push(block);
} else { } else {
drives.push(Drive { drives.push(Drive {
path: drv_path, object_path: drv_path,
id: String::new(), id: String::new(),
model: String::new(), model: String::new(),
ejectable: false, ejectable: false,
@ -94,7 +97,7 @@ pub async fn collect_all() -> udisks2::Result<Vec<Drive>> {
let mut fstab = Drive { let mut fstab = Drive {
id: "fstab".to_owned(), id: "fstab".to_owned(),
path: "fstab".to_owned(), object_path: "fstab".to_owned(),
model: "fstab".to_owned(), model: "fstab".to_owned(),
ejectable: false, ejectable: false,
blocks: Vec::new(), blocks: Vec::new(),
@ -107,22 +110,55 @@ pub async fn collect_all() -> udisks2::Result<Vec<Drive>> {
.and_then(|d| d.blocks.iter_mut().find(|b| b.dev == i.dev)); .and_then(|d| d.blocks.iter_mut().find(|b| b.dev == i.dev));
if let Some(block) = block { if let Some(block) = block {
block.mount = i.path; block.mount = i.path;
block.mounted = i.mounted;
} else { } else {
fstab.blocks.push(Block { fstab.blocks.push(Block {
id: i.dev.clone(), object_path: String::new(),
dev: i.dev, dev: i.dev,
label: String::new(), label: String::new(),
mount: i.path, mount: i.path,
fstype: i.fs, fstype: i.fs,
mounted: i.mounted,
}); });
} }
} }
drives.push(fstab); drives.push(fstab);
drives.sort_by_cached_key(|b| b.path.clone()); drives.sort_by_cached_key(|b| b.object_path.clone());
for i in &mut drives { for i in &mut drives {
i.blocks.sort_by_cached_key(|b| b.dev.clone()); i.blocks.sort_by_cached_key(|b| b.dev.clone());
} }
return Ok(drives); Ok(drives)
}
pub async fn mount(block: &Block) -> udisks2::Result<()> {
let mut drives: Vec<Drive> = Vec::new();
let client = udisks2::Client::new().await?;
client
.object(block.object_path.clone())?
.filesystem()
.await?
.mount(HashMap::new())
.await?;
// client.part
Ok(())
}
pub async fn unmount(block: &Block) -> udisks2::Result<()> {
let mut drives: Vec<Drive> = Vec::new();
let client = udisks2::Client::new().await?;
client
.object(block.object_path.clone())?
.filesystem()
.await?
.unmount(HashMap::new())
.await?;
// client.part
Ok(())
} }

View file

@ -3,48 +3,109 @@ mod mountpoints;
use std::{ use std::{
ffi::{OsStr, OsString}, ffi::{OsStr, OsString},
io::stderr,
os::unix::ffi::{OsStrExt, OsStringExt}, os::unix::ffi::{OsStrExt, OsStringExt},
sync::{Arc, Mutex}, sync::Arc,
time::Duration,
}; };
use crossterm::event::{self, Event, KeyCode, KeyEventKind}; use crossterm::{
event::{Event, EventStream, KeyCode, KeyEventKind},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use drives::Drive;
use mountpoints::MountPoint; use mountpoints::MountPoint;
use ratatui::{ use ratatui::{
layout::{Alignment, Constraint, Layout}, layout::{Alignment, Constraint, Layout},
prelude::CrosstermBackend,
style::Color, style::Color,
text::{Line, Text}, text::{Line, Text},
widgets::{ widgets::{
Block, BorderType, Padding, Paragraph, Row, StatefulWidget, Table, TableState, Widget, Wrap, Block, BorderType, Padding, Paragraph, Row, StatefulWidget, Table, TableState, Widget, Wrap,
}, },
Frame, Frame, Terminal,
}; };
use tokio::sync::Mutex;
use tokio_stream::StreamExt;
enum Command {
None,
Mount(String),
Umount(String),
}
#[tokio::main] #[tokio::main]
async fn main() -> udisks2::Result<()> { async fn main() -> udisks2::Result<()> {
let mut terminal = ratatui::init(); enable_raw_mode().unwrap();
execute!(stderr(), EnterAlternateScreen).unwrap();
let mut terminal = Terminal::new(CrosstermBackend::new(stderr())).unwrap();
let mut ts = TableState::new(); let mut ts = TableState::new();
let period = Duration::from_secs_f32(1.0 / 10.0);
let mut interval = tokio::time::interval(period);
let mut events = EventStream::new();
let state: Arc<Mutex<Vec<drives::Drive>>> = Arc::new(Mutex::new(Vec::new()));
let s = state.clone();
tokio::spawn(async move {
loop {
let drv = drives::collect_all().await.unwrap();
s.lock().await.clone_from(&drv);
tokio::time::sleep(Duration::from_millis(500)).await;
}
});
let mut output = String::new();
let mut last_status = String::new();
loop { loop {
let drv = drives::collect_all().await?; let drv = state.lock().await.clone();
let mut selected: Option<drives::Block> = None;
terminal terminal
.draw(|f| draw(f, &mut ts, &drv)) .draw(|f| draw(f, &mut ts, &drv, &mut selected, &last_status))
.expect("failed to draw frame"); .expect("failed to draw frame");
if let Event::Key(key) = event::read().unwrap() { tokio::select! {
if key.kind == KeyEventKind::Press { _ = interval.tick() => { },
match key.code { Some(Ok(event)) = events.next() => {
KeyCode::Up => ts.select_previous(), if let Event::Key(key) = event {
KeyCode::Down => ts.select_next(), if key.kind == KeyEventKind::Press {
KeyCode::Esc => break, match key.code {
_ => {} KeyCode::Up | KeyCode::Char('k') => ts.select_previous(),
KeyCode::Down | KeyCode::Char('j') => ts.select_next(),
KeyCode::Char('m') => if let Some(b) = &selected {
last_status = format!("{:?}", drives::mount(b).await);
}
KeyCode::Char('u') => if let Some(b) = &selected {
last_status = format!("{:?}", drives::unmount(b).await);
}
KeyCode::Esc | KeyCode::Char('q') => break,
KeyCode::Enter => {
output = selected.unwrap().mount.unwrap();
break;
}
_ => {}
}
}
} }
} },
} }
} }
ratatui::restore();
disable_raw_mode().unwrap();
execute!(stderr(), LeaveAlternateScreen).unwrap();
println!("{output}");
Ok(()) Ok(())
} }
fn draw(frame: &mut Frame, state: &mut TableState, drv: &[drives::Drive]) { fn draw(
frame: &mut Frame,
state: &mut TableState,
drv: &[drives::Drive],
selected: &mut Option<drives::Block>,
last_status: &str,
) {
let text = Text::raw("Hello World!"); let text = Text::raw("Hello World!");
frame.render_widget(text, frame.area()); frame.render_widget(text, frame.area());
@ -61,12 +122,22 @@ fn draw(frame: &mut Frame, state: &mut TableState, drv: &[drives::Drive]) {
.border_style(Color::Yellow); .border_style(Color::Yellow);
block.clone().render(layout[0], frame.buffer_mut()); block.clone().render(layout[0], frame.buffer_mut());
let rows = drv.iter().flat_map(|d| &d.blocks).map(|i| { let rows: Vec<drives::Block> = drv.iter().flat_map(|d| d.blocks.clone()).collect();
state
.selected()
.and_then(|n| rows.get(n).cloned())
.clone_into(selected);
let rows = rows.iter().map(|i| {
Row::new(vec![ Row::new(vec![
i.dev.clone(), i.dev.clone(),
i.label.clone(), i.label.clone(),
i.mount.clone().unwrap_or_default(), i.mount.clone().unwrap_or_default(),
"M".to_owned(), match i.mounted {
true => "M".to_owned(),
false => "O".to_owned(),
},
]) ])
}); });
let widths = [ let widths = [
@ -81,8 +152,10 @@ fn draw(frame: &mut Frame, state: &mut TableState, drv: &[drives::Drive]) {
StatefulWidget::render(table, block.inner(frame.area()), frame.buffer_mut(), state); StatefulWidget::render(table, block.inner(frame.area()), frame.buffer_mut(), state);
frame.render_widget( frame.render_widget(
Paragraph::new("j - UP, k - DOWN, l - Goto mountpoint\nm - Mount, u - Unmount, e - Eject") Paragraph::new(format!(
.wrap(Wrap { trim: true }), "j - UP, k - DOWN, l - Goto mountpoint, m - Mount, u - Unmount, e - Eject\n{selected:?} {last_status:?}"
))
.wrap(Wrap { trim: true }),
layout[1], layout[1],
); );
} }

View file

@ -5,10 +5,22 @@ pub struct MountPoint {
pub dev: String, pub dev: String,
pub path: Option<String>, pub path: Option<String>,
pub fs: String, pub fs: String,
pub mounted: bool,
} }
impl MountPoint { impl MountPoint {
pub fn collect_from_file(path: &str) -> Vec<MountPoint> { pub fn collect_from_file(path: &str) -> Vec<MountPoint> {
const FSTYPE_IGNORE: [&str; 8] = [
"tmpfs",
"swap",
"devtmpfs",
"devpts",
"hugetlbfs",
"mqueue",
"fuse.portal",
"fuse.gvfsd-fuse",
];
const PATH_IGNORE: [&str; 3] = ["/tmp", "/sys", "/proc"];
std::io::BufReader::new(std::fs::File::open(PathBuf::from(path)).unwrap()) std::io::BufReader::new(std::fs::File::open(PathBuf::from(path)).unwrap())
.lines() .lines()
.map_while(Result::ok) .map_while(Result::ok)
@ -21,17 +33,16 @@ impl MountPoint {
.into(), .into(),
path: Some(parts.next()?.to_string()), path: Some(parts.next()?.to_string()),
fs: parts.next()?.into(), fs: parts.next()?.into(),
mounted: false,
}) })
}) })
.filter(|p| !FSTYPE_IGNORE.contains(&p.fs.as_str()))
.filter(|p| { .filter(|p| {
p.fs != "tmpfs" && p.fs != "swap" if let Some(p) = &p.path {
&& p.path.clone().is_some_and(|p| { !PATH_IGNORE.iter().any(|ignore| p.starts_with(ignore))
!p.starts_with("/sys") } else {
&& !p.starts_with("/tmp") false
&& !p.starts_with("/run") }
&& !p.starts_with("/proc")
&& !p.starts_with("/dev")
})
}) })
.collect() .collect()
} }
@ -44,12 +55,14 @@ impl MountPoint {
.into_iter() .into_iter()
.filter(|p| !mnt.iter().any(|f| f.path == p.path)) .filter(|p| !mnt.iter().any(|f| f.path == p.path))
.map(|p| MountPoint { .map(|p| MountPoint {
dev: p.dev, mounted: false,
path: None, ..p
fs: p.fs,
}) })
.collect(); .collect();
mnt.into_iter().chain(fstab).collect() mnt.into_iter()
.map(|m| MountPoint { mounted: true, ..m })
.chain(fstab)
.collect()
} }
} }