codeberg_cli/actions/issue/
list.rs1use forgejo_api::structs::{Issue, IssueListIssuesQuery};
2
3use crate::actions::GeneralArgs;
4use crate::render::json::JsonToStdout;
5use crate::render::option::{option_debug_display, option_display};
6use crate::render::spinner::spin_until_ready;
7use crate::types::context::BergContext;
8use crate::types::git::OwnerRepo;
9use crate::types::output::OutputMode;
10
11use clap::Parser;
12
13#[derive(Parser, Debug)]
15pub struct ListIssueArgs {
16 #[arg(short, long, value_name = "N")]
18 pub count: Option<u32>,
19}
20
21impl ListIssueArgs {
22 pub async fn run(self, general_args: GeneralArgs) -> anyhow::Result<()> {
23 let ctx = BergContext::new(self, general_args).await?;
24 let OwnerRepo { repo, owner } = ctx.owner_repo()?;
25 let (_, mut issues_list) = spin_until_ready(ctx.client.issue_list_issues(
26 owner.as_str(),
27 repo.as_str(),
28 IssueListIssuesQuery {
29 page: ctx.args.count.as_ref().map(|_| 1),
30 limit: ctx.args.count,
31 ..Default::default()
32 },
33 ))
34 .await?;
35
36 issues_list.retain(|issue| issue.pull_request.is_none());
37
38 match general_args.output_mode {
39 OutputMode::Pretty => {
40 present_issues_list(&ctx, issues_list);
41 }
42 OutputMode::Json => issues_list.print_json()?,
43 }
44
45 Ok(())
46 }
47}
48
49fn present_issues_list(ctx: &BergContext<ListIssueArgs>, issues: Vec<Issue>) {
50 let issues_empty = issues.is_empty();
51
52 let mut table = ctx.make_table().add_table((!issues_empty).then(|| {
53 let mut inner_table = ctx.make_table();
54 inner_table
55 .set_header(vec!["Number", "Status", "Name", "Labels"])
56 .add_rows(issues.into_iter().map(|issue| {
57 let Issue {
58 title,
59 number,
60 labels,
61 state,
62 ..
63 } = issue;
64 let labels = labels.map(|labels| {
65 labels
66 .into_iter()
67 .map(|label| option_display(&label.name))
68 .collect::<Vec<_>>()
69 .join(",")
70 });
71 vec![
72 option_display(&number),
73 option_debug_display(&state),
74 option_display(&title),
75 option_display(&labels),
76 ]
77 }));
78 inner_table
79 }));
80
81 table.set_header(vec![format!(
82 "Issues{}",
83 if issues_empty {
84 " (empty)"
85 } else {
86 Default::default()
87 }
88 )]);
89
90 println!("{table}", table = table.show());
91}