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
use {
    super::*,
    snafu::prelude::*,
    std::fs,
};

/// the labelling of a file-system, that
/// is the pair (label, fs)
#[derive(Debug, Clone)]
pub struct Labelling {
    pub label: String,
    pub fs_name: String,
}

/// try to find all file-system labels
///
/// An error can't be excluded as not all systems expose
/// this information the way lfs-core reads it.
pub fn read_labels() -> Result<Vec<Labelling>, Error> {
    let path = "/dev/disk/by-label";
    let entries = fs::read_dir(path).context(CantReadDirSnafu { path })?;
    let labels = entries
        .filter_map(|entry| entry.ok())
        .filter_map(|entry| {
            let md = entry.metadata().ok()?;
            let file_type = md.file_type();
            if !file_type.is_symlink() {
                return None;
            }
            let label = sys::decode_string(entry.file_name().to_string_lossy());
            let linked_path = fs::read_link(entry.path())
                .map(|path| path.to_string_lossy().to_string())
                .ok()?;
            let fs_name = format!(
                "/dev/{}",
                linked_path.strip_prefix("../../")?,
            );
            Some(Labelling { label, fs_name })
        })
        .collect();
    Ok(labels)
}