use forgejo_api::structs::{Issue, IssueListIssuesQuery, IssueListIssuesQueryState};
use miette::IntoDiagnostic;
use crate::actions::GlobalArgs;
use crate::render::json::JsonToStdout;
use crate::render::option::{option_debug_display, option_display};
use crate::render::spinner::spin_until_ready;
use crate::types::api::state_type::ViewStateType;
use crate::types::context::BergContext;
use crate::types::git::OwnerRepo;
use crate::types::output::OutputMode;
use clap::Parser;
#[derive(Parser, Debug)]
pub struct ListIssueArgs {
#[arg(short, long, value_enum, default_value_t = ViewStateType::Open)]
pub state: ViewStateType,
}
impl ListIssueArgs {
pub async fn run(self, global_args: GlobalArgs) -> miette::Result<()> {
let ctx = BergContext::new(self, global_args).await?;
let OwnerRepo { repo, owner } = ctx.owner_repo()?;
let state = match ctx.args.state {
ViewStateType::Closed => IssueListIssuesQueryState::Closed,
ViewStateType::Open => IssueListIssuesQueryState::Open,
ViewStateType::All => IssueListIssuesQueryState::All,
};
let (_, mut issues_list) = spin_until_ready(
ctx.client
.issue_list_issues(
owner.as_str(),
repo.as_str(),
IssueListIssuesQuery {
state: Some(state),
..Default::default()
},
)
.send(),
)
.await
.into_diagnostic()?;
issues_list.retain(|issue| issue.pull_request.is_none());
match ctx.global_args.output_mode {
OutputMode::Pretty => {
present_issues_list(&ctx, issues_list);
}
OutputMode::Json => issues_list.print_json()?,
}
Ok(())
}
}
fn present_issues_list(ctx: &BergContext<ListIssueArgs>, issues: Vec<Issue>) {
let issues_empty = issues.is_empty();
let table = ctx
.make_table()
.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| option_display(&label.name))
.collect::<Vec<_>>()
.join(",")
});
vec![
option_display(&number),
option_debug_display(&state),
option_display(&title),
option_display(&labels),
]
}));
let header = format!(
"Issues{}",
if issues_empty {
" (empty)"
} else {
Default::default()
}
);
let underscore = "=".repeat(header.len());
let out = [header, underscore, table.show()].join("\n");
println!("{out}");
}