Move the issue type to libjirac
This commit is contained in:
parent
5b47f3d5e9
commit
6102233bc5
10 changed files with 163 additions and 171 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -980,6 +980,10 @@ checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
|||
[[package]]
|
||||
name = "libjirac"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
|
|
|
@ -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<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{}",
|
||||
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<dyn std::error::Error>> {
|
||||
let j = serde_json::to_string_pretty(issues)?;
|
||||
println!("{}", j);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn exec(output: FormatMode, jql: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = JiraConfig::load().map_err(|e| format!("Configuration error: {}", e))?;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ mod cmd;
|
|||
mod jira_config;
|
||||
mod jql;
|
||||
mod term;
|
||||
mod types;
|
||||
|
||||
use clap::Parser;
|
||||
use cli::{Cli, Commands};
|
||||
|
|
|
@ -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<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{}",
|
||||
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<dyn std::error::Error>> {
|
||||
let j = serde_json::to_string_pretty(issues)?;
|
||||
println!("{}", j);
|
||||
Ok(())
|
||||
}
|
|
@ -4,3 +4,5 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
serde = { workspace = true }
|
||||
chrono = { workspace = true }
|
80
crates/libjirac/src/entities/issue.rs
Normal file
80
crates/libjirac/src/entities/issue.rs
Normal file
|
@ -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<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,
|
||||
}
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue