diff --git a/Cargo.lock b/Cargo.lock index 8d3ec02..6a7807c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -980,6 +980,10 @@ checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libjirac" version = "0.1.0" +dependencies = [ + "chrono", + "serde", +] [[package]] name = "libredox" diff --git a/crates/jirac/src/cmd/search.rs b/crates/jirac/src/cmd/search.rs index e2dd050..fd8dff2 100644 --- a/crates/jirac/src/cmd/search.rs +++ b/crates/jirac/src/cmd/search.rs @@ -1,6 +1,79 @@ use crate::cli::FormatMode; use crate::jira_config::JiraConfig; -use crate::types::issue::{display_issues_compact, display_issues_json, display_issues_pretty}; +use crate::term::hyperlink; +use crossterm::style::{Color, Stylize}; +use libjirac::entities::issue::JiraIssue; +use std::io::Write; + +pub fn display_issues_pretty(issues: &[JiraIssue]) -> Result<(), Box> { + println!("Found {} issues:", issues.len()); + println!("{:-<80}", ""); + + for issue in issues { + let mut tw = tabwriter::TabWriter::new(vec![]); + writeln!(tw, "{}:\t{}", "Key".blue(), issue.key)?; + writeln!(tw, "{}:\t{}", "Summary".blue(), issue.fields.summary)?; + writeln!(tw, "{}:\t{}", "Status".blue(), issue.fields.status.name)?; + writeln!( + tw, + "{}:\t{}", + "Created".blue(), + issue.fields.created.with_timezone(&chrono::Local) + )?; + writeln!( + tw, + "{}:\t{}", + "Due Date".blue(), + match issue.fields.due_date { + None => "None".to_string(), + Some(x) => x.to_string(), + } + )?; + writeln!( + tw, + "{}", + &hyperlink(&issue.href, &"Open Issue".green().to_string()) + )?; + + tw.flush().unwrap(); + + let written = String::from_utf8(tw.into_inner().unwrap()).unwrap(); + print!("{}", written); + println!("{:-<80}", ""); + } + + Ok(()) +} + +pub fn display_issues_compact(issues: &[JiraIssue]) -> Result<(), Box> { + println!("Found {} issues:", issues.len()); + println!("{:-<80}", ""); + + let mut tw = tabwriter::TabWriter::new(vec![]); + for issue in issues { + writeln!( + tw, + "{}:\t{}", + hyperlink( + &issue.href, + &issue.key.clone().blue().underline(Color::Blue).to_string() + ), + issue.fields.summary.clone().green() + )?; + } + + tw.flush().unwrap(); + let written = String::from_utf8(tw.into_inner().unwrap()).unwrap(); + print!("{}", written); + + Ok(()) +} + +pub fn display_issues_json(issues: &[JiraIssue]) -> Result<(), Box> { + let j = serde_json::to_string_pretty(issues)?; + println!("{}", j); + Ok(()) +} pub async fn exec(output: FormatMode, jql: &str) -> Result<(), Box> { let config = JiraConfig::load().map_err(|e| format!("Configuration error: {}", e))?; diff --git a/crates/jirac/src/cmd/view.rs b/crates/jirac/src/cmd/view.rs index 752fe5d..b868fff 100644 --- a/crates/jirac/src/cmd/view.rs +++ b/crates/jirac/src/cmd/view.rs @@ -1,8 +1,8 @@ use crate::cli::FormatMode; use crate::jira_config::JiraConfig; use crate::term::hyperlink; -use crate::types::issue::JiraIssue; use crossterm::style::{Color, Stylize}; +use libjirac::entities::issue::JiraIssue; use std::io::Write; async fn fetch_issue( diff --git a/crates/jirac/src/jql.rs b/crates/jirac/src/jql.rs index a281f3d..de6fc6a 100644 --- a/crates/jirac/src/jql.rs +++ b/crates/jirac/src/jql.rs @@ -1,5 +1,5 @@ use crate::jira_config::JiraConfig; -use crate::types::issue::JiraIssue; +use libjirac::entities::issue::JiraIssue; use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE}; use serde::Deserialize; diff --git a/crates/jirac/src/main.rs b/crates/jirac/src/main.rs index 199f533..a2cd3c1 100644 --- a/crates/jirac/src/main.rs +++ b/crates/jirac/src/main.rs @@ -3,7 +3,6 @@ mod cmd; mod jira_config; mod jql; mod term; -mod types; use clap::Parser; use cli::{Cli, Commands}; diff --git a/crates/jirac/src/types/issue.rs b/crates/jirac/src/types/issue.rs deleted file mode 100644 index ac009a8..0000000 --- a/crates/jirac/src/types/issue.rs +++ /dev/null @@ -1,153 +0,0 @@ -use crate::term::hyperlink; -use crossterm::style::{Color, Stylize}; -use serde::{Deserialize, Serialize}; -use std::io::Write; - -#[derive(Debug, Deserialize, Serialize)] -pub struct JiraIssue { - pub key: String, - #[serde(rename = "self")] - pub href: String, - pub fields: JiraIssueResponseFields, -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct JiraIssueResponseFields { - pub summary: String, - pub description: Option, - pub status: Status, - pub created: chrono::DateTime, - pub priority: Priority, - pub assignee: Person, - pub reporter: Person, - pub creator: Person, - #[serde(rename = "duedate")] - pub due_date: Option, - pub comment: Option, - pub votes: Votes, -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct Status { - pub name: String, -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct Priority { - pub name: String, - pub id: String, -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct Person { - #[serde(rename = "self")] - pub href: String, - #[serde(rename = "displayName")] - pub display_name: String, - #[serde(rename = "accountId")] - pub account_id: String, - #[serde(rename = "emailAddress")] - pub email_address: Option, -} - -#[derive(Debug, Default, Clone, Deserialize, Serialize)] -pub struct Comments { - pub total: u32, - #[serde(rename = "maxResults")] - pub max_results: u32, - #[serde(rename = "startAt")] - pub start_at: u32, - pub comments: Vec, -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct Comment { - #[serde(rename = "self")] - pub href: String, - pub id: String, - pub author: Person, - pub body: String, - #[serde(rename = "updateAuthor")] - pub update_author: Person, - pub created: chrono::DateTime, -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct Votes { - #[serde(rename = "self")] - pub href: String, - #[serde(rename = "votes")] - pub count: i32, - #[serde(rename = "hasVoted")] - pub has_voted: bool, -} - -pub fn display_issues_pretty(issues: &[JiraIssue]) -> Result<(), Box> { - println!("Found {} issues:", issues.len()); - println!("{:-<80}", ""); - - for issue in issues { - let mut tw = tabwriter::TabWriter::new(vec![]); - writeln!(tw, "{}:\t{}", "Key".blue(), issue.key)?; - writeln!(tw, "{}:\t{}", "Summary".blue(), issue.fields.summary)?; - writeln!(tw, "{}:\t{}", "Status".blue(), issue.fields.status.name)?; - writeln!( - tw, - "{}:\t{}", - "Created".blue(), - issue.fields.created.with_timezone(&chrono::Local) - )?; - writeln!( - tw, - "{}:\t{}", - "Due Date".blue(), - match issue.fields.due_date { - None => "None".to_string(), - Some(x) => x.to_string(), - } - )?; - writeln!( - tw, - "{}", - &hyperlink(&issue.href, &"Open Issue".green().to_string()) - )?; - - tw.flush().unwrap(); - - let written = String::from_utf8(tw.into_inner().unwrap()).unwrap(); - print!("{}", written); - println!("{:-<80}", ""); - } - - Ok(()) -} - -pub fn display_issues_compact(issues: &[JiraIssue]) -> Result<(), Box> { - println!("Found {} issues:", issues.len()); - println!("{:-<80}", ""); - - let mut tw = tabwriter::TabWriter::new(vec![]); - for issue in issues { - writeln!( - tw, - "{}:\t{}", - hyperlink( - &issue.href, - &issue.key.clone().blue().underline(Color::Blue).to_string() - ), - issue.fields.summary.clone().green() - )?; - } - - tw.flush().unwrap(); - let written = String::from_utf8(tw.into_inner().unwrap()).unwrap(); - print!("{}", written); - - Ok(()) -} - -pub fn display_issues_json(issues: &[JiraIssue]) -> Result<(), Box> { - let j = serde_json::to_string_pretty(issues)?; - println!("{}", j); - Ok(()) -} diff --git a/crates/libjirac/Cargo.toml b/crates/libjirac/Cargo.toml index 3e24ca4..cda4626 100644 --- a/crates/libjirac/Cargo.toml +++ b/crates/libjirac/Cargo.toml @@ -4,3 +4,5 @@ version = "0.1.0" edition = "2021" [dependencies] +serde = { workspace = true } +chrono = { workspace = true } \ No newline at end of file diff --git a/crates/jirac/src/types.rs b/crates/libjirac/src/entities.rs similarity index 100% rename from crates/jirac/src/types.rs rename to crates/libjirac/src/entities.rs diff --git a/crates/libjirac/src/entities/issue.rs b/crates/libjirac/src/entities/issue.rs new file mode 100644 index 0000000..bfdfe57 --- /dev/null +++ b/crates/libjirac/src/entities/issue.rs @@ -0,0 +1,80 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Deserialize, Serialize)] +pub struct JiraIssue { + pub key: String, + #[serde(rename = "self")] + pub href: String, + pub fields: JiraIssueResponseFields, +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct JiraIssueResponseFields { + pub summary: String, + pub description: Option, + pub status: Status, + pub created: chrono::DateTime, + pub priority: Priority, + pub assignee: Person, + pub reporter: Person, + pub creator: Person, + #[serde(rename = "duedate")] + pub due_date: Option, + pub comment: Option, + pub votes: Votes, +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct Status { + pub name: String, +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct Priority { + pub name: String, + pub id: String, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Person { + #[serde(rename = "self")] + pub href: String, + #[serde(rename = "displayName")] + pub display_name: String, + #[serde(rename = "accountId")] + pub account_id: String, + #[serde(rename = "emailAddress")] + pub email_address: Option, +} + +#[derive(Debug, Default, Clone, Deserialize, Serialize)] +pub struct Comments { + pub total: u32, + #[serde(rename = "maxResults")] + pub max_results: u32, + #[serde(rename = "startAt")] + pub start_at: u32, + pub comments: Vec, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Comment { + #[serde(rename = "self")] + pub href: String, + pub id: String, + pub author: Person, + pub body: String, + #[serde(rename = "updateAuthor")] + pub update_author: Person, + pub created: chrono::DateTime, +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct Votes { + #[serde(rename = "self")] + pub href: String, + #[serde(rename = "votes")] + pub count: i32, + #[serde(rename = "hasVoted")] + pub has_voted: bool, +} diff --git a/crates/libjirac/src/lib.rs b/crates/libjirac/src/lib.rs index b93cf3f..0b8f0b5 100644 --- a/crates/libjirac/src/lib.rs +++ b/crates/libjirac/src/lib.rs @@ -1,14 +1 @@ -pub fn add(left: u64, right: u64) -> u64 { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} +pub mod entities;