From f05461f1f7a615026d084aa193ca54a65aaef558 Mon Sep 17 00:00:00 2001 From: Daan Boerlage Date: Tue, 21 Jan 2025 22:03:11 +0100 Subject: [PATCH] Add output formatters --- readme.md | 12 ++++++------ src/cli.rs | 37 ++++++++++++++++++++++++++----------- src/cmd/search.rs | 38 +++++++++++++++++++------------------- src/cmd/view.rs | 14 +++++++------- src/main.rs | 8 ++++---- 5 files changed, 62 insertions(+), 47 deletions(-) diff --git a/readme.md b/readme.md index b742336..66bf364 100644 --- a/readme.md +++ b/readme.md @@ -78,8 +78,8 @@ Find issues currently assigned to you Usage: jirac list [OPTIONS] Options: - --json Print json rather than pretty print - -h, --help Print help + -o, --output Pick an output formatter [default: pretty] [possible values: pretty, json] + -h, --help Print help ``` ### Search for issues @@ -93,8 +93,8 @@ Arguments: A JQL string Options: - --json Print JSON rather than pretty print - -h, --help Print help + -o, --output Pick an output formatter [default: pretty] [possible values: pretty, json] + -h, --help Print help ``` Use [JQL](https://support.atlassian.com/jira-software-cloud/docs/use-advanced-search-with-jira-query-language-jql/) to search for Issues. @@ -116,8 +116,8 @@ Arguments: An issue key, for example, KEY-123 Options: - --json Print JSON rather than pretty print - -h, --help Print help + -o, --output Pick an output formatter [default: pretty] [possible values: pretty, json] + -h, --help Print help ``` ```sh diff --git a/src/cli.rs b/src/cli.rs index b60e63d..ede5de4 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,4 +1,4 @@ -use clap::{Parser, Subcommand}; +use clap::{Parser, Subcommand, ValueEnum}; use std::path::PathBuf; #[derive(Parser)] @@ -8,12 +8,27 @@ pub struct Cli { pub command: Commands, } +#[derive(ValueEnum, Debug, Copy, Clone, Eq, PartialEq)] +pub enum FormatMode { + Pretty, + Json, +} + +impl std::fmt::Display for FormatMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.to_possible_value() + .expect("no values are skipped") + .get_name() + .fmt(f) + } +} + #[derive(Subcommand)] pub enum Commands { /// Create an issue Create { /// The project key in which to create the issue - #[arg(long)] + #[arg(short, long)] project: Option, /// Open the new issue in a browser @@ -26,15 +41,15 @@ pub enum Commands { }, /// Find issues currently assigned to you List { - /// Print JSON rather than pretty print - #[arg(long)] - json: bool, + /// Pick an output formatter + #[arg(short, long, default_value_t = FormatMode::Pretty)] + output: FormatMode, }, /// Search for issues Search { - /// Print JSON rather than pretty print - #[arg(long)] - json: bool, + /// Pick an output formatter + #[arg(short, long, default_value_t = FormatMode::Pretty)] + output: FormatMode, /// A JQL string #[arg(value_name = "JQL")] @@ -42,9 +57,9 @@ pub enum Commands { }, /// View an issue View { - /// Print JSON rather than pretty print - #[arg(long)] - json: bool, + /// Pick an output formatter + #[arg(short, long, default_value_t = FormatMode::Pretty)] + output: FormatMode, /// An issue key, for example, KEY-123 #[arg(value_name = "ISSUE")] diff --git a/src/cmd/search.rs b/src/cmd/search.rs index eee42ab..5781443 100644 --- a/src/cmd/search.rs +++ b/src/cmd/search.rs @@ -1,31 +1,31 @@ +use crate::cli::FormatMode; use crate::jira_config::JiraConfig; use crate::types::issue::{display_issues_json, display_issues_pretty}; -pub async fn exec(json: bool, jql: &str) -> Result<(), Box> { +pub async fn exec(output: FormatMode, jql: &str) -> Result<(), Box> { let config = JiraConfig::load().map_err(|e| format!("Configuration error: {}", e))?; - if !json { + if output != FormatMode::Json { println!("Searching for issues..."); } - match crate::jql::run(&config, jql).await { - Ok(response) => { - if json { - if response.issues.is_empty() { - println!("[]"); - } else { - display_issues_json(&response.issues)?; - } - } else if response.issues.is_empty() { - println!("No results found for query."); - } else { - display_issues_pretty(&response.issues)?; - println!("Total issues: {}", response.total); - } - } - Err(e) => { - eprintln!("Error fetching issues: {}", e); + let result = match crate::jql::run(&config, jql).await { + Ok(x) => x, + Err(reason) => { + eprintln!("Error fetching issues: {}", reason); std::process::exit(1); } + }; + + match (output, result.issues.is_empty()) { + (FormatMode::Pretty, false) => { + display_issues_pretty(&result.issues)?; + println!("Total issues: {}", result.total); + } + (FormatMode::Pretty, true) => { + println!("No results found for query."); + } + (FormatMode::Json, false) => display_issues_json(&result.issues)?, + (FormatMode::Json, true) => println!("[]"), } Ok(()) diff --git a/src/cmd/view.rs b/src/cmd/view.rs index 68d1021..72cdeda 100644 --- a/src/cmd/view.rs +++ b/src/cmd/view.rs @@ -1,3 +1,4 @@ +use crate::cli::FormatMode; use crate::jira_config::JiraConfig; use crate::types::issue::JiraIssue; use crossterm::style::{Color, Stylize}; @@ -112,9 +113,9 @@ pub fn json_print(issues: &JiraIssue) -> Result<(), Box> Ok(()) } -pub async fn exec(json: bool, issue_key: &str) -> Result<(), Box> { +pub async fn exec(output: FormatMode, issue_key: &str) -> Result<(), Box> { let config = JiraConfig::load().map_err(|e| format!("Configuration error: {}", e))?; - if !json { + if output != FormatMode::Json { println!("Loading issue data"); } @@ -138,11 +139,10 @@ pub async fn exec(json: bool, issue_key: &str) -> Result<(), Box pretty_print(&fetched_issue)?, + FormatMode::Json => json_print(&fetched_issue)?, + } Ok(()) } diff --git a/src/main.rs b/src/main.rs index b42e90b..33d5ec2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,12 +18,12 @@ async fn main() -> Result<(), Box> { open, markdown_file, } => cmd::create::create(project, open, markdown_file).await?, - Commands::List { json } => { + Commands::List { output } => { let jql = "assignee = currentUser() AND resolution = Unresolved order by updated DESC"; - cmd::search::exec(json, jql).await? + cmd::search::exec(output, jql).await? } - Commands::Search { json, jql } => cmd::search::exec(json, &jql).await?, - Commands::View { json, issue } => cmd::view::exec(json, &issue).await?, + Commands::Search { output, jql } => cmd::search::exec(output, &jql).await?, + Commands::View { output, issue } => cmd::view::exec(output, &issue).await?, Commands::Init { url, email, token } => { JiraConfig::init(url, email, token).await?; println!("Configuration initialized successfully!");