use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::globals::OUTDIR;
use std::fs::{remove_dir_all, File};
use std::io::BufReader;
use std::io::Read;
use std::path::Path;
use std::process::Output;
use log::info;
use miette::{IntoDiagnostic, Result};
use pipelight_error::PipelightError;
#[derive(Default, Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
pub struct Io {
pub uuid: Uuid,
pub stdin: Option<String>,
pub stdout: Option<String>,
pub stderr: Option<String>,
}
impl Io {
pub fn clean(&self) -> Result<(), std::io::Error> {
let path = format!("{}/{}", *OUTDIR.lock().unwrap(), self.uuid);
let path = Path::new(&path);
if path.exists() {
remove_dir_all(path)?;
}
Ok(())
}
pub fn read(&mut self) -> Result<(), std::io::Error> {
let stdout_path = format!("{}/{}/1", *OUTDIR.lock().unwrap(), self.uuid);
let stderr_path = format!("{}/{}/2", *OUTDIR.lock().unwrap(), self.uuid);
info!("read subprocess stdout from tmp file at {}", stdout_path);
let f = File::open(stdout_path)?;
let mut buf_reader = BufReader::new(f);
let mut stdout = String::new();
buf_reader.read_to_string(&mut stdout)?;
info!("Read subprocess stderr from tmp file at {}", stderr_path);
let f = File::open(stderr_path)?;
let mut buf_reader = BufReader::new(f);
let mut stderr = String::new();
buf_reader.read_to_string(&mut stderr)?;
*self = Io {
stdin: self.stdin.to_owned(),
stdout: Some(stdout),
stderr: Some(stderr),
..*self
};
Ok(())
}
}
impl From<&Output> for Io {
fn from(output: &Output) -> Io {
let stdout_str = String::from_utf8(output.stdout.to_owned()).unwrap();
let stderr_str = String::from_utf8(output.stderr.to_owned()).unwrap();
let mut stdout = None;
if !stdout_str.is_empty() {
stdout = Some(stdout_str.to_owned());
}
let mut stderr = None;
if !stderr_str.is_empty() {
stderr = Some(stderr_str.to_owned());
}
Io {
stdin: None,
uuid: Uuid::new_v4(),
stdout,
stderr,
}
}
}