pub mod asset;
pub mod conformance;
pub mod event;
pub mod manifest;
pub mod receipt;
pub mod telemetry;
use std::io::Read;
#[derive(Debug)]
pub enum CliError {
Usage(String),
Validation(String),
Input(String),
}
impl CliError {
pub fn exit_code(&self) -> u8 {
match self {
CliError::Validation(_) => 1,
CliError::Usage(_) => 2,
CliError::Input(_) => 3,
}
}
pub fn message(&self) -> &str {
match self {
CliError::Usage(m) | CliError::Validation(m) | CliError::Input(m) => m,
}
}
}
pub fn read_stdin(label: &str) -> Result<String, CliError> {
let mut buf = String::new();
std::io::stdin()
.read_to_string(&mut buf)
.map_err(|err| CliError::Input(format!("failed to read {label} from stdin: {err}")))?;
if buf.trim().is_empty() {
return Err(CliError::Input(format!("{label}: stdin is empty")));
}
Ok(buf)
}
pub fn parse_stdin_json<T: serde::de::DeserializeOwned>(label: &str) -> Result<T, CliError> {
let buf = read_stdin(label)?;
serde_json::from_str::<T>(&buf)
.map_err(|err| CliError::Input(format!("{label}: invalid JSON: {err}")))
}
pub fn print_json<T: serde::Serialize>(value: &T) -> Result<(), CliError> {
let json = serde_json::to_string_pretty(value)
.map_err(|err| CliError::Input(format!("failed to serialize output: {err}")))?;
println!("{json}");
Ok(())
}