1use anyhow::Result;
26use async_std::task;
27use ferrix_lib::sys::KModules;
28use serde::{Serialize, Deserialize};
29use std::process::Command;
30
31use crate::DataLoadingState;
32
33pub async fn get_kmodules() -> DataLoadingState<KResult> {
34 let output = task::spawn_blocking(|| {
35 Command::new("pkexec")
36 .arg("/usr/bin/ferrix-polkit")
37 .arg("kmods")
38 .output()
39 })
40 .await;
41
42 if let Err(why) = output {
43 return DataLoadingState::Error(why.to_string());
44 }
45 let output = output.unwrap();
46 if !output.status.success() {
47 return DataLoadingState::Error(format!(
48 "[ferrix-polkit] Non-zero return code:\n{}",
49 String::from_utf8_lossy(&output.stderr)
50 ));
51 }
52
53 let json_str = String::from_utf8_lossy(&output.stdout);
54 let json_data = KResult::from_json(&json_str);
55
56 match json_data {
57 Ok(data) => DataLoadingState::Loaded(data),
58 Err(why) => DataLoadingState::Error(why.to_string()),
59 }
60}
61
62#[derive(Debug, Serialize, Deserialize, Clone)]
63#[serde(untagged)]
64pub enum KResult {
65 Ok { data: KModules },
66 Err { error: String },
67}
68
69impl KResult {
70 pub fn new() -> Self {
71 match KModules::new() {
72 Ok(data) => Self::Ok { data, },
73 Err(why) => Self::Err { error: why.to_string(), },
74 }
75 }
76
77 pub fn to_json(&self) -> Result<String> {
78 Ok(serde_json::to_string(&self)?)
79 }
80
81 pub fn from_json(json: &str) -> Result<Self> {
82 Ok(serde_json::from_str(json)?)
83 }
84}