use forgejo_api::structs::{Issue, IssueListIssuesQuery};
use crate::actions::GeneralArgs;
use crate::render::option::{option_debug_display, option_display};
use crate::render::spinner::spin_until_ready;
use crate::types::context::BergContext;
use crate::types::git::OwnerRepo;
use clap::Parser;
#[derive(Parser, Debug)]
pub struct ListIssueArgs {
#[arg(short, long, value_name = "N")]
pub count: Option<u32>,
}
impl ListIssueArgs {
pub async fn run(self, general_args: GeneralArgs) -> anyhow::Result<()> {
let _ = general_args;
let ctx = BergContext::new(self).await?;
let OwnerRepo { repo, owner } = ctx.owner_repo()?;
let mut issues_list = spin_until_ready(ctx.client.issue_list_issues(
owner.as_str(),
repo.as_str(),
IssueListIssuesQuery {
page: ctx.args.count.as_ref().map(|_| 1),
limit: ctx.args.count,
..Default::default()
},
))
.await?;
issues_list.retain(|issue| issue.pull_request.is_none());
present_issues_list(&ctx, issues_list);
Ok(())
}
}
fn present_issues_list(ctx: &BergContext<ListIssueArgs>, issues: Vec<Issue>) {
let issues_empty = issues.is_empty();
let mut table = ctx.make_table();
table.set_header(vec![format!(
"Issues{}",
issues_empty.then_some(" (empty)").unwrap_or_default()
)]);
let mut table_inner = ctx.make_table();
if !issues_empty {
table_inner
.set_header(vec!["Number", "Status", "Name", "Labels"])
.add_rows(issues.into_iter().map(|issue| {
let Issue {
title,
number,
labels,
state,
..
} = issue;
let labels = labels.map(|labels| {
labels
.into_iter()
.map(|label| format!("{}", option_display(&label.name)))
.collect::<Vec<_>>()
.join(",")
});
vec![
option_display(&number),
option_debug_display(&state),
option_display(&title),
option_display(&labels),
]
}));
table.add_row(vec![format!("{table_inner}")]);
}
println!("{table}");
}