feat: add guts for handling outputs and rendering them
This commit is contained in:
1 parent
bfe779cf9a
commit
03c1c3329f
2 files changed
+91
No files matched your search
+58
@@ -0,0 +1,58 @@
|
||||
mod cli;
|
||||
mod output;
|
||||
|
||||
use clap::{Parser, error::ErrorKind};
|
||||
use cli::Cli;
|
||||
|
||||
use output::render_error;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct CliError {
|
||||
pub code: i32,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
impl CliError {
|
||||
pub fn info(message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
code: 0,
|
||||
message: message.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn runtime(message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
code: 1,
|
||||
message: message.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn usage(message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
code: 2,
|
||||
message: message.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type CliResult<T> = Result<T, CliError>;
|
||||
|
||||
pub async fn run(_cli: Cli) -> CliResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn parse_cli_from<I, T>(args: I) -> CliResult<Cli>
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
T: Into<std::ffi::OsString> + Clone,
|
||||
{
|
||||
Cli::try_parse_from(args).map_err(|e| match e.kind() {
|
||||
ErrorKind::DisplayHelp | ErrorKind::DisplayVersion => CliError::info(e.to_string()),
|
||||
_ => CliError::usage(e.to_string()),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn render_cli_error(err: &CliError, pretty: bool) -> String {
|
||||
render_error(err, pretty)
|
||||
.unwrap_or_else(|_| "{\"error\":{\"code\":1,\"message\":\"Unexpected error.\"}}".to_string())
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{CliError, CliResult};
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct ErrorBody<'a> {
|
||||
pub code: i32,
|
||||
pub message: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct ErrorEnvelope<'a> {
|
||||
pub error: ErrorBody<'a>,
|
||||
}
|
||||
|
||||
pub fn render_json<T: Serialize>(value: &T, pretty: bool) -> CliResult<String> {
|
||||
if pretty {
|
||||
serde_json::to_string_pretty(value).map_err(|_| CliError::runtime("Failed to serialize output"))
|
||||
} else {
|
||||
serde_json::to_string(value).map_err(|_| CliError::runtime("Failed to serialize output"))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_error(err: &CliError, pretty: bool) -> CliResult<String> {
|
||||
let envelope = ErrorEnvelope {
|
||||
error: ErrorBody {
|
||||
code: err.code,
|
||||
message: &err.message,
|
||||
},
|
||||
};
|
||||
|
||||
render_json(&envelope, pretty)
|
||||
}
|
||||
Reference in new issue
Block a user