|
|
|
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<T> = Result<DataResult<T>, 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<T: DeserializeOwned>(argv: &[&str]) -> PanelResult<T> {
|
|
|
|
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<T: DeserializeOwned>(args: impl Into<String> + Display) -> PanelResult<T> {
|
|
|
|
println!("Executing 'u_panel {}'", &args);
|
|
|
|
let splitted = split(args.into().as_ref()).unwrap();
|
|
|
|
Self::output_argv(
|
|
|
|
splitted
|
|
|
|
.iter()
|
|
|
|
.map(|s| s.as_ref())
|
|
|
|
.collect::<Vec<&str>>()
|
|
|
|
.as_ref(),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn status_is_ok<T: DeserializeOwned>(data: PanelResult<T>) -> T {
|
|
|
|
match data.unwrap() {
|
|
|
|
DataResult::Ok(r) => r,
|
|
|
|
DataResult::Err(e) => panic!("Panel failed: {}", e),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn check_status(args: impl Into<String> + Display) {
|
|
|
|
let result: PanelResult<Value> = Self::output(args);
|
|
|
|
Self::status_is_ok(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn check_output<T: DeserializeOwned>(args: impl Into<String> + Display) -> T {
|
|
|
|
let result = Self::output(args);
|
|
|
|
Self::status_is_ok(result)
|
|
|
|
}
|
|
|
|
}
|