use serde::de::DeserializeOwned; use serde_json::{from_slice, Value}; use shlex::split; use std::fmt::Display; use std::process::{Command, Output}; use u_lib::{ datatypes::DataResult, utils::{bytes_to_string, ProcOutput}, }; const PANEL_BINARY: &str = "/u_panel"; type PanelResult = Result, String>; pub struct Panel; impl Panel { fn run(args: &[&str]) -> Output { Command::new(PANEL_BINARY) .arg("--json") .args(args) .output() .unwrap() } pub fn output_argv(argv: &[&str]) -> PanelResult { let result = Self::run(argv); let output = ProcOutput::from_output(&result).to_appropriate(); from_slice(&output).map_err(|e| { eprintln!( "Failed to decode panel response: '{}'", bytes_to_string(&output) ); e.to_string() }) } pub fn output(args: impl Into + Display) -> PanelResult { println!("Executing '{PANEL_BINARY} {}'", &args); let splitted = split(args.into().as_ref()).unwrap(); Self::output_argv( splitted .iter() .map(|s| s.as_ref()) .collect::>() .as_ref(), ) } fn status_is_ok(data: PanelResult) -> T { match data.unwrap() { DataResult::Ok(r) => r, DataResult::Err(e) => panic!("Panel failed: {}", e), } } pub fn check_status(args: impl Into + Display) { let result: PanelResult = Self::output(args); Self::status_is_ok(result); } pub fn check_output(args: impl Into + Display) -> T { let result = Self::output(args); Self::status_is_ok(result) } }