You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
3.1 KiB
119 lines
3.1 KiB
3 years ago
|
use serde::de::DeserializeOwned;
|
||
3 years ago
|
use serde_json::{from_slice, Value};
|
||
2 years ago
|
use std::fmt::{Debug, Display};
|
||
3 years ago
|
use std::process::{Command, Output};
|
||
2 years ago
|
use u_lib::{conv::bytes_to_string, proc_output::ProcOutput, types::PanelResult};
|
||
3 years ago
|
|
||
|
const PANEL_BINARY: &str = "/u_panel";
|
||
|
|
||
|
pub struct Panel;
|
||
|
|
||
|
impl Panel {
|
||
|
fn run(args: &[&str]) -> Output {
|
||
1 year ago
|
Command::new(PANEL_BINARY)
|
||
|
.env("RUST_LOG", "u_lib=debug")
|
||
|
.args(args)
|
||
|
.output()
|
||
|
.unwrap()
|
||
3 years ago
|
}
|
||
|
|
||
3 years ago
|
pub fn output_argv<T: DeserializeOwned>(argv: &[&str]) -> PanelResult<T> {
|
||
|
let result = Self::run(argv);
|
||
2 years ago
|
let output = ProcOutput::from_output(&result);
|
||
|
|
||
1 year ago
|
let stderr = output.get_stderr();
|
||
|
if !stderr.is_empty() {
|
||
|
println!(
|
||
|
"\n*** PANEL DEBUG OUTPUT START***\n{}\n*** PANEL DEBUG OUTPUT END ***\n",
|
||
|
String::from_utf8_lossy(stderr)
|
||
|
);
|
||
|
}
|
||
|
|
||
2 years ago
|
match from_slice(output.get_stdout()) {
|
||
|
Ok(r) => r,
|
||
|
Err(e) => {
|
||
2 years ago
|
eprintln!(
|
||
2 years ago
|
"Failed to decode panel response: ###'{}'###",
|
||
|
bytes_to_string(output.get_stdout())
|
||
2 years ago
|
);
|
||
2 years ago
|
panic!("{e}")
|
||
|
}
|
||
|
}
|
||
3 years ago
|
}
|
||
|
|
||
2 years ago
|
pub fn output<T: DeserializeOwned + Debug>(args: impl IntoArgs) -> PanelResult<T> {
|
||
|
eprintln!(">>> {PANEL_BINARY} {}", args.display());
|
||
|
let splitted = args.into_args();
|
||
2 years ago
|
let result = Self::output_argv(
|
||
3 years ago
|
splitted
|
||
|
.iter()
|
||
|
.map(|s| s.as_ref())
|
||
|
.collect::<Vec<&str>>()
|
||
|
.as_ref(),
|
||
2 years ago
|
);
|
||
|
match &result {
|
||
1 year ago
|
PanelResult::Ok(r) => eprintln!("+<< {r:#?}"),
|
||
|
PanelResult::Err(e) => eprintln!("!<< {e:#?}"),
|
||
2 years ago
|
}
|
||
|
result
|
||
3 years ago
|
}
|
||
|
|
||
2 years ago
|
fn status_is_ok<T: DeserializeOwned + Debug>(data: PanelResult<T>) -> T {
|
||
|
match data {
|
||
|
PanelResult::Ok(r) => r,
|
||
2 years ago
|
PanelResult::Err(e) => panic!("Panel failed: {e}"),
|
||
3 years ago
|
}
|
||
3 years ago
|
}
|
||
|
|
||
2 years ago
|
pub fn check_status(args: impl IntoArgs) {
|
||
3 years ago
|
let result: PanelResult<Value> = Self::output(args);
|
||
3 years ago
|
Self::status_is_ok(result);
|
||
3 years ago
|
}
|
||
|
|
||
2 years ago
|
pub fn check_output<T: DeserializeOwned + Debug>(args: impl IntoArgs) -> T {
|
||
3 years ago
|
let result = Self::output(args);
|
||
3 years ago
|
Self::status_is_ok(result)
|
||
3 years ago
|
}
|
||
|
}
|
||
2 years ago
|
|
||
|
pub trait IntoArgs {
|
||
|
fn into_args(self) -> Vec<String>;
|
||
|
fn display(&self) -> String;
|
||
|
}
|
||
|
|
||
|
impl IntoArgs for String {
|
||
|
fn into_args(self) -> Vec<String> {
|
||
|
<Self as AsRef<str>>::as_ref(&self).into_args()
|
||
|
}
|
||
|
|
||
|
fn display(&self) -> String {
|
||
|
self.clone()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl IntoArgs for &str {
|
||
|
fn into_args(self) -> Vec<String> {
|
||
|
shlex::split(self.as_ref()).unwrap()
|
||
|
}
|
||
|
|
||
|
fn display(&self) -> String {
|
||
|
self.to_string()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl<S, const N: usize> IntoArgs for [S; N]
|
||
|
where
|
||
|
S: Display,
|
||
|
{
|
||
|
fn into_args(self) -> Vec<String> {
|
||
|
self.into_iter().map(|s| s.to_string()).collect()
|
||
|
}
|
||
|
|
||
|
fn display(&self) -> String {
|
||
|
self.iter()
|
||
|
.map(|s| format!(r#""{s}""#))
|
||
|
.collect::<Vec<String>>()
|
||
|
.join(" ")
|
||
|
}
|
||
|
}
|