ferrix_app/
dmi.rs

1/* dmi.rs
2 *
3 * Copyright 2025 Michail Krasnov <mskrasnov07@ya.ru>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: GPL-3.0-or-later
19 */
20
21//! DMI Service Provider
22
23use 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}