Repository: pop-os/popsicle (language: rust)

Issue:
Show Device Names
Show device names from `/sys/class/block`

For example, when using `/dev/sdd`, the following files have useful information:
- `/sys/class/block/sdd/device/vendor`
- `/sys/class/block/sdd/device/model`


Discussion / hints:

Fix patch:
diff --git a/gtk/src/block.rs b/gtk/src/block.rs
new file mode 100644
index 0000000..e76d762
--- /dev/null
+++ b/gtk/src/block.rs
@@ -0,0 +1,45 @@
+use std::default::Default;
+use std::fs::File;
+use std::io::Read;
+use std::path::{Path, PathBuf};
+
+fn read_file(path: &Path) -> String {
+    File::open(path)
+        .and_then(|mut file| {
+            let mut string = String::new();
+            file.read_to_string(&mut string)
+                .map(|_| string.trim().to_owned())
+        })
+        .unwrap_or(String::default())
+}
+
+pub struct BlockDevice {
+    path: PathBuf,
+}
+
+impl BlockDevice {
+    pub fn new(path: &Path) -> Option<BlockDevice> {
+        path.file_name().and_then(|file_name| {
+            let path = PathBuf::from("/sys/class/block/").join(file_name);
+            if path.exists() {
+                Some(BlockDevice { path })
+            } else {
+                None
+            }
+        })
+    }
+
+    pub fn vendor(&self) -> String { read_file(&self.path.join("device/vendor")) }
+
+    pub fn model(&self) -> String { read_file(&self.path.join("device/model")) }
+
+    pub fn label(&self) -> String {
+        let model = self.model();
+        let vendor = self.vendor();
+        if vendor.is_empty() {
+            model.replace("_", " ")
+        } else {
+            [&vendor, " ", &model].concat().replace("_", " ")
+        }
+    }
+}
diff --git a/gtk/src/main.rs b/gtk/src/main.rs
index 123454c..bcfdb71 100644
--- a/gtk/src/main.rs
+++ b/gtk/src/main.rs
@@ -6,6 +6,7 @@ extern crate muff;
 extern crate pango;
 extern crate sha3;
 
+mod block;
 mod image;
 mod ui;
 
@@ -15,6 +16,8 @@ use std::sync::mpsc::channel;
 use std::thread;
 use ui::{App, Connect};
 
+pub use block::BlockDevice;
+
 fn main() {
     let (sender, receiver) = channel::<PathBuf>();
     let app = App::new(sender);
diff --git a/gtk/src/ui/state.rs b/gtk/src/ui/state.rs
index e4551da..74065fc 100644
--- a/gtk/src/ui/state.rs
+++ b/gtk/src/ui/state.rs
@@ -1,4 +1,5 @@
 use super::{hash, App, FlashTask, OpenDialog};
+use super::super::BlockDevice;
 
 use std::mem;
 use std::ops::{Deref, DerefMut};
@@ -169,7 +170,17 @@ impl Connect for App {
                     device_list.clear();
                     for device in &devices {
                         let name = Path::new(&device).canonicalize().unwrap();
-                        let button = CheckButton::new_with_label(&name.to_string_lossy());
+                        let button = if let Some(block) = BlockDevice::new(&name) {
+                            CheckButton::new_with_label(&[
+                                &block.label(),
+                                " (",
+                                &name.to_string_lossy(),
+                                ")",
+                            ].concat())
+                        } else {
+                            CheckButton::new_with_label(&name.to_string_lossy())
+                        };
+
                         list.insert(&button, -1);
                         device_list.push((device.clone(), button));
                     }
@@ -214,13 +225,20 @@ impl Connect for App {
                         let finished = Arc::new(AtomicUsize::new(0));
                         let bar = ProgressBar::new();
                         bar.set_hexpand(true);
-                        let label = Label::new(
-                            Path::new(&disk_path)
-                                .canonicalize()
-                                .unwrap()
-                                .to_str()
-                                .unwrap(),
-                        );
+
+                        let label = {
+                            let disk_path = Path::new(&disk_path).canonicalize().unwrap();
+                            if let Some(block) = BlockDevice::new(&disk_path) {
+                                Label::new(
+                                    [&block.label(), " (", &disk_path.to_string_lossy(), ")"]
+                                        .concat()
+                                        .as_str(),
+                                )
+                            } else {
+                                Label::new(disk_path.to_string_lossy().as_ref())
+                            }
+                        };
+
                         label.set_justify(Justification::Right);
                         label
                             .get_style_context()


Test patch: