codeberg_cli/actions/issue/
list.rs

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