Skip to main content

ferrix_lib/
lib.rs

1/* lib.rs
2 *
3 * Copyright 2025-2026 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//! ferrix-lib is a library for obtaining information about the
22//! hardware and software of a PC running Linux OS.
23//!
24//! ## Examples
25//! Get all information about hardware and software (NOTE: needed
26//! `root` permissions!):
27//! ```no-test
28//! use ferrix_lib::Ferrix;
29//!
30//! let data = Ferrix::new()?; // get all data
31//!
32//! let json_str = data.to_json()?; // get machine-readable JSON from this data
33//! let pjson_str = data.to_json_pretty()?; // get human-readable JSON
34//! let xml_str = data.to_xml()?; // get XML
35//! ```
36//!
37//! Get information about CPU:
38//! ```no-test
39//! use ferrix_lib::cpu::Processors;
40//! let proc = Processors::new()?;
41//!
42//! let json_str = data.to_json()?;
43//! let pjson_str = data.to_json_pretty()?;
44//! ```
45
46pub mod battery;
47pub mod cpu;
48pub mod cpu_freq;
49pub mod desktop;
50pub mod dmi;
51pub mod drm;
52pub mod firmware;
53pub mod init;
54pub mod net;
55pub mod parts;
56pub mod ram;
57pub mod resources;
58pub mod soft;
59pub mod sys;
60pub mod vmstat;
61pub mod vulnerabilities;
62
63pub mod traits;
64pub mod utils;
65
66use crate::traits::ToPlainText;
67use anyhow::Result;
68use serde::Serialize;
69
70pub const FX_LIB_VERSION: &str = env!("CARGO_PKG_VERSION");
71
72#[derive(Debug, Serialize)]
73pub struct Ferrix {
74    pub cpu: cpu::Processors,
75    pub ram: ram::RAM,
76    pub swaps: ram::Swaps,
77    pub dmi: dmi::DMITable,
78    pub drm: drm::Video,
79    pub sys: sys::Sys,
80    pub init: init::SystemdServices,
81}
82
83impl Ferrix {
84    pub async fn new() -> Result<Self> {
85        let conn = zbus::Connection::system().await?;
86        Ok(Self {
87            cpu: cpu::Processors::new()?,
88            ram: ram::RAM::new()?,
89            swaps: ram::Swaps::new()?,
90            dmi: dmi::DMITable::new()?,
91            drm: drm::Video::new()?,
92            sys: sys::Sys::new()?,
93            init: init::SystemdServices::new_from_connection(&conn).await?,
94        })
95    }
96
97    fn _update(&mut self) -> Result<()> {
98        self.cpu = cpu::Processors::new()?;
99        self.ram = ram::RAM::new()?;
100        self.swaps = ram::Swaps::new()?;
101        self.sys.update()?;
102
103        Ok(())
104    }
105
106    pub async fn update(&mut self, conn: &zbus::Connection) -> Result<()> {
107        self._update()?;
108        self.init = init::SystemdServices::new_from_connection(&conn).await?;
109        Ok(())
110    }
111
112    pub async fn update1(&mut self) -> Result<()> {
113        self._update()?;
114        let conn = zbus::Connection::system().await?;
115        self.init = init::SystemdServices::new_from_connection(&conn).await?;
116        Ok(())
117    }
118
119    /// Performs serialization of structure data in JSON.
120    ///
121    /// The returned value will be a SINGLE LINE of JSON data
122    /// intended for reading by third-party software or for
123    /// transmission over the network.
124    pub fn to_json(&self) -> Result<String> {
125        Ok(serde_json::to_string(&self)?)
126    }
127
128    /// Performs serialization in "pretty" JSON
129    ///
130    /// JSON will contain unnecessary newline transitions and spaces
131    /// to visually separate the blocks. It is well suited for human
132    /// reading and analysis.
133    pub fn to_json_pretty(&self) -> Result<String> {
134        Ok(serde_json::to_string_pretty(&self)?)
135    }
136
137    /// Performs data serialization in XML format
138    pub fn to_xml(&self) -> Result<String> {
139        let xml = XMLData::from(self);
140        let data = XMLFerrixData::from(&xml);
141        data.to_xml()
142    }
143}
144
145impl ToPlainText for Ferrix {
146    fn to_plain(&self) -> String {
147        let mut s = format!("");
148        s += &self.cpu.to_plain();
149        s += &self.init.to_plain();
150
151        s
152    }
153}
154
155#[derive(Serialize)]
156struct XMLFerrixData<'a> {
157    data: &'a XMLData<'a>,
158}
159
160#[derive(Serialize)]
161struct XMLData<'a> {
162    cpu: &'a cpu::Processors,
163    ram: &'a ram::RAM,
164    dmi: dmi::DMITableXml<'a>,
165    sys: &'a sys::Sys,
166    init: &'a init::SystemdServices,
167}
168
169impl<'a> From<&'a Ferrix> for XMLData<'a> {
170    fn from(value: &'a Ferrix) -> Self {
171        Self {
172            cpu: &value.cpu,
173            ram: &value.ram,
174            dmi: dmi::DMITableXml::from(&value.dmi),
175            sys: &value.sys,
176            init: &value.init,
177        }
178    }
179}
180
181impl<'a> XMLFerrixData<'a> {
182    fn to_xml(&self) -> Result<String> {
183        Ok(xml_serde::to_string(&self)?)
184    }
185}
186
187impl<'a> From<&'a XMLData<'a>> for XMLFerrixData<'a> {
188    fn from(value: &'a XMLData) -> Self {
189        Self { data: value }
190    }
191}