1use {
2 super::*,
3 snafu::prelude::*,
4 std::fs,
5};
6
7#[derive(Debug, Clone)]
10pub struct Labelling {
11 pub label: String,
12 pub fs_name: String,
13}
14
15pub fn get_label(
16 fs_name: &str,
17 labellings: Option<&[Labelling]>,
18) -> Option<String> {
19 labellings.as_ref().and_then(|labels| {
20 labels
21 .iter()
22 .find(|label| label.fs_name == fs_name)
23 .map(|label| label.label.clone())
24 })
25}
26
27pub fn read_by(by_kind: &str) -> Result<Vec<Labelling>, Error> {
33 let path = format!("/dev/disk/by-{by_kind}");
34 let entries = fs::read_dir(&path).context(CantReadDirSnafu { path })?;
35 let labels = entries
36 .filter_map(|entry| entry.ok())
37 .filter_map(|entry| {
38 let md = entry.metadata().ok()?;
39 let file_type = md.file_type();
40 if !file_type.is_symlink() {
41 return None;
42 }
43 let label = sys::decode_string(entry.file_name().to_string_lossy());
44 let linked_path = fs::read_link(entry.path())
45 .map(|path| path.to_string_lossy().to_string())
46 .ok()?;
47 let fs_name = format!("/dev/{}", linked_path.strip_prefix("../../")?,);
48 Some(Labelling { label, fs_name })
49 })
50 .collect();
51 Ok(labels)
52}