1#[cfg(target_os = "linux")]
2use {
3 super::*,
4 snafu::prelude::*,
5 std::fs,
6};
7
8#[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
27#[cfg(target_os = "linux")]
33pub fn read_by(by_kind: &str) -> Result<Vec<Labelling>, Error> {
34 let path = format!("/dev/disk/by-{by_kind}");
35 let entries = fs::read_dir(&path).context(CantReadDirSnafu { path })?;
36 let labels = entries
37 .filter_map(|entry| entry.ok())
38 .filter_map(|entry| {
39 let md = entry.metadata().ok()?;
40 let file_type = md.file_type();
41 if !file_type.is_symlink() {
42 return None;
43 }
44 let label = sys::decode_string(entry.file_name().to_string_lossy());
45 let linked_path = fs::read_link(entry.path())
46 .map(|path| path.to_string_lossy().to_string())
47 .ok()?;
48 let fs_name = format!("/dev/{}", linked_path.strip_prefix("../../")?,);
49 Some(Labelling { label, fs_name })
50 })
51 .collect();
52 Ok(labels)
53}