leenfetch_core/modules/linux/system/
model.rs1use std::fs;
2
3pub fn get_model() -> Option<String> {
4 if std::path::Path::new("/system/app/").exists()
6 && std::path::Path::new("/system/priv-app/").exists()
7 {
8 return Some("Android Device".to_string()); }
10
11 let paths = [
12 (
13 "/sys/devices/virtual/dmi/id/board_vendor",
14 "/sys/devices/virtual/dmi/id/board_name",
15 ),
16 (
17 "/sys/devices/virtual/dmi/id/product_name",
18 "/sys/devices/virtual/dmi/id/product_version",
19 ),
20 ("/sys/firmware/devicetree/base/model", ""),
21 ("/tmp/sysinfo/model", ""),
22 ];
23
24 let mut model = String::new();
25
26 for (file1, file2) in paths {
27 if std::path::Path::new(file1).exists() {
28 model.push_str(&read_first_line(file1).unwrap_or_default());
29 if !file2.is_empty() && std::path::Path::new(file2).exists() {
30 model.push(' ');
31 model.push_str(&read_first_line(file2).unwrap_or_default());
32 }
33 break;
34 }
35 }
36
37 if model.is_empty() {
38 return None;
39 }
40
41 let cleaned = cleanup_model_string(&model);
42 Some(cleaned)
43}
44
45fn read_first_line<P: AsRef<std::path::Path>>(path: P) -> Option<String> {
47 fs::read_to_string(path)
48 .ok()
49 .and_then(|s| s.lines().next().map(|line| line.trim().to_string()))
50}
51
52fn cleanup_model_string(model: &str) -> String {
54 let mut s = model.to_string();
55
56 let garbage = [
57 "To be filled by O.E.M.",
58 "To Be Filled",
59 "OEM",
60 "Not Applicable",
61 "System Product Name",
62 "System Version",
63 "Undefined",
64 "Default string",
65 "Not Specified",
66 "Type1ProductConfigId",
67 "INVALID",
68 "All Series",
69 "�",
70 ];
71
72 for g in garbage {
73 s = s.replace(g, "").trim().to_string();
74 }
75
76 if s.starts_with("Standard PC") {
77 s = format!("KVM/QEMU ({})", model.trim());
78 } else if s.starts_with("OpenBSD") {
79 s = format!("vmm ({})", model.trim());
80 }
81
82 s
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn test_cleanup_garbage() {
91 let raw = "To be filled by O.E.M.";
92 let cleaned = cleanup_model_string(raw);
93 assert_eq!(cleaned, "");
94
95 let raw = "Standard PC (i440FX)";
96 let cleaned = cleanup_model_string(raw);
97 assert!(cleaned.contains("KVM/QEMU"));
98 }
99
100 #[test]
101 fn test_model_maybe_exists() {
102 let model = get_model();
103 assert!(model.is_none() || !model.as_ref().unwrap().is_empty());
104 }
105}