1use anyhow::Result;
24use async_std::task;
25use ferrix_lib::dmi::{Baseboard, Bios, Chassis, Processor};
26use serde::{Deserialize, Serialize};
27use std::process::Command;
28
29use crate::load_state::{LoadState, ToLoadState};
30
31pub async fn get_dmi_data() -> LoadState<DMIData> {
32 let output = task::spawn_blocking(|| {
33 Command::new("pkexec")
34 .arg("ferrix-polkit")
35 .arg("dmi")
36 .output()
37 })
38 .await;
39
40 if let Err(why) = output {
41 return LoadState::Error(why.to_string());
42 }
43 let output = output.unwrap();
44 if output.status.code().unwrap_or(0) != 0 {
45 return LoadState::Error(format!(
46 "[ferrix-polkit] Non-zero return code:\n{}",
47 String::from_utf8_lossy(&output.stderr)
48 ));
49 }
50
51 let json_str = String::from_utf8_lossy(&output.stdout);
52 let json_data = DMIData::from_json(&json_str);
53
54 match json_data {
55 Ok(data) => LoadState::Loaded(data),
56 Err(why) => LoadState::Error(why.to_string()),
57 }
58}
59
60#[derive(Debug, Serialize, Deserialize, Clone)]
61pub struct DMIData {
62 pub bios: LoadState<Bios>,
63 pub baseboard: LoadState<Baseboard>,
64 pub chassis: LoadState<Chassis>,
65 pub processor: LoadState<Processor>,
66}
67
68impl DMIData {
69 pub fn new() -> Self {
70 Self {
71 bios: Bios::new().to_load_state(),
72 baseboard: Baseboard::new().to_load_state(),
73 chassis: Chassis::new().to_load_state(),
74 processor: Processor::new().to_load_state(),
75 }
76 }
77
78 pub fn to_json(&self) -> Result<String> {
79 let contents = serde_json::to_string(&self)?;
80 Ok(contents)
81 }
82
83 pub fn from_json(json: &str) -> Result<Self> {
84 Ok(serde_json::from_str(json)?)
85 }
86}