use serde::{Deserialize, Serialize}; use serde_json::{Value, json}; use std::{cmp::Ordering::Equal, collections::HashMap}; use sysinfo::{System, Users}; #[derive(Debug, Serialize, Deserialize)] pub struct SoftwareInfo { name: String, count: usize, } #[derive(Debug, Serialize, Deserialize)] pub struct ExternalInfo { softwares: Vec, } #[allow(dead_code)] pub fn get_struct() -> ExternalInfo { let mut system = System::new_all(); system.refresh_all(); let users = &Users::new_with_refreshed_list(); let mut grouped_processes: HashMap> = HashMap::new(); for process in system.processes().values() { let name = process.name().to_str().unwrap().to_string(); let user_id = process.user_id(); let is_user_owned = user_id.is_some_and(|uid| { users .list() .iter() .any(|u| u.id() == uid && u.name() != "root") }); if is_user_owned && !name.trim().is_empty() && !name.starts_with('[') { grouped_processes .entry(name) .or_default() .push(process.pid().as_u32() as i32); } } let mut softwares = Vec::new(); let mut grouped_vec: Vec<_> = grouped_processes.into_iter().collect(); grouped_vec.sort_by(|a, b| match b.1.len().cmp(&a.1.len()) { Equal => a.0.to_lowercase().cmp(&b.0.to_lowercase()), other => other, }); for (name, pids) in grouped_vec { softwares.push(SoftwareInfo { name, count: pids.len(), }); } ExternalInfo { softwares } } #[allow(dead_code)] pub fn get_json() -> Value { json!(get_struct()) }