use std::fs;
use std::io::{Read, Write};
use std::path::Path;
use serde::de::DeserializeOwned;
use crate::error::Result;
use crate::reporter::Payload;
use crate::values::OutputFormat;
const STDIO: &str = "-";
pub struct Io;
impl Io {
pub fn read_bytes(path: &Path) -> Result<Vec<u8>> {
if path == Path::new(STDIO) {
let mut buffer = Vec::new();
std::io::stdin().read_to_end(&mut buffer)?;
return Ok(buffer);
}
Ok(fs::read(path)?)
}
pub fn read_json<T: DeserializeOwned>(path: &Path) -> Result<T> {
let bytes = Self::read_bytes(path)?;
Ok(serde_json::from_slice(&bytes)?)
}
pub fn write_bytes(path: &Path, data: &[u8]) -> Result<()> {
Ok(fs::write(path, data)?)
}
pub fn write_stdout(data: &[u8]) -> Result<()> {
let mut stdout = std::io::stdout().lock();
stdout.write_all(data)?;
stdout.flush()?;
Ok(())
}
pub fn output_binary_data(
format: OutputFormat,
data: &[u8],
output: Option<&Path>,
) -> Result<Option<Payload>> {
match output {
Some(path) => {
Self::write_bytes(path, data)?;
Ok(Some(Payload::written(data, path.display().to_string())))
}
None => match format {
OutputFormat::Json => Ok(Some(Payload::inline(data))),
OutputFormat::Text => {
Self::write_stdout(data)?;
Ok(None)
}
},
}
}
}