150 lines
3.9 KiB
Rust
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(())
|
|
}
|