1use crate::{is_linux, InfoTrait};
2use std::error::Error;
3use std::process::Command;
4
5#[derive(Default, Clone, Debug)]
6pub struct Gpu {
7 pub name: Option<String>,
8 pub vendor: Option<String>,
9 pub driver: Option<String>,
10}
11
12#[derive(Default, Clone, Debug)]
13pub struct Gpus(pub Vec<Gpu>);
14
15impl InfoTrait for Gpus {
16 fn get() -> Result<Self, Box<dyn Error>> {
17 let _ = is_linux()?;
18 let mut gpus = Self::default();
19
20 let command = Command::new("lspci").arg("-nnk").output()?;
21
22 let mut since = 0;
23
24 std::str::from_utf8(&command.stdout)?
25 .trim()
26 .split('\n')
27 .for_each(|i| {
28 if i.contains("Display") || i.contains("3D") || i.contains("VGA") {
29 let mut gpu = Gpu::default();
30 let inf = i.split(':').collect::<Vec<&str>>();
31 if inf.len() > 1 {
32 gpu.name = Some(inf[2].trim().to_string());
33 gpu.vendor = Some(
34 inf[2].split_whitespace().collect::<Vec<&str>>()[0]
35 .trim()
36 .to_string(),
37 );
38 gpus.0.push(gpu);
39 }
40 since = 0;
41 } else {
42 if since < 3 && gpus.0.len() > 0 {
43 if i.contains("driver") {
44 let inf = i.split(':').collect::<Vec<&str>>();
45 if inf.len() > 1 {
46 let mut gpu = gpus.0.last().unwrap().clone();
47 gpu.driver = Some(inf[1].trim().to_string());
48 gpus.0.pop();
49 gpus.0.push(gpu);
50 }
51 }
52 }
53 since += 1;
54 }
55 });
56 Ok(gpus)
57 }
58}