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