jirac/src/types/issue.rs

150 lines
3.9 KiB
Rust

use crate::term::hyperlink;
use crossterm::style::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<String>,
pub status: Status,
pub created: chrono::DateTime<chrono::Utc>,
pub priority: Priority,
pub assignee: Person,
pub reporter: Person,
pub creator: Person,
#[serde(rename = "duedate")]
pub due_date: Option<chrono::NaiveDate>,
pub comment: Option<Comments>,
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<String>,
}
#[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<Comment>,
}
#[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<chrono::Utc>,
}
#[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<dyn std::error::Error>> {
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<dyn std::error::Error>> {
println!("Found {} issues:", issues.len());
println!("{:-<80}", "");
let mut tw = tabwriter::TabWriter::new(vec![]);
for issue in issues {
writeln!(
tw,
"{}:\t{}",
issue.key.clone().blue(),
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<dyn std::error::Error>> {
let j = serde_json::to_string_pretty(issues)?;
println!("{}", j);
Ok(())
}