Skip to main content

codeberg_cli/actions/notification/
list.rs

1use crate::render::json::JsonToStdout;
2use crate::types::context::BergContext;
3use crate::types::output::OutputMode;
4use crate::{actions::GlobalArgs, render::option::option_display};
5use forgejo_api::structs::{NotificationThread, NotifyGetListQuery};
6
7use clap::Parser;
8use miette::IntoDiagnostic;
9
10#[derive(Debug, Parser)]
11pub struct ListNotificationArgs {
12    /// just list everything
13    #[arg(short, long, default_value_t = false)]
14    pub all: bool,
15
16    /// filter notifications by status
17    #[arg(long, default_values_t = ["Unread", "Pinned"].map(String::from).to_vec())]
18    pub status_types: Vec<String>,
19
20    /// filter notifications by subject type
21    #[arg(long)]
22    pub subject_type: Option<String>,
23
24    /// filter notifications by date
25    #[arg(short, long)]
26    pub dates: bool,
27
28    /// control how many pages of notifications should be shown
29    #[arg(short, long, default_value_t = 1)]
30    pub page: usize,
31
32    /// control how many notifications each page should hold
33    #[arg(short, long, default_value_t = usize::MAX)]
34    pub limit: usize,
35}
36
37impl ListNotificationArgs {
38    pub async fn run(self, global_args: GlobalArgs) -> miette::Result<()> {
39        let ctx = BergContext::new(self, global_args).await?;
40
41        let (_, notification_threads_list) = ctx
42            .client
43            .notify_get_list(NotifyGetListQuery {
44                ..Default::default()
45            })
46            .await
47            .into_diagnostic()?;
48
49        match ctx.global_args.output_mode {
50            OutputMode::Pretty => {
51                tracing::debug!("{notification_threads_list:?}");
52                present_notification_threads(&ctx, notification_threads_list);
53            }
54            OutputMode::Json => notification_threads_list.print_json()?,
55        }
56
57        Ok(())
58    }
59}
60
61fn present_notification_threads(
62    ctx: &BergContext<ListNotificationArgs>,
63    notification_threads_list: Vec<NotificationThread>,
64) {
65    let header = if notification_threads_list.is_empty() {
66        "Notification Threads (empty)"
67    } else {
68        "Notification Threads"
69    };
70
71    let table = ctx.make_table().set_header(vec![header]).add_rows(
72        notification_threads_list
73            .into_iter()
74            .map(|notification_thread| {
75                vec![option_display(
76                    &notification_thread
77                        .subject
78                        .as_ref()
79                        .and_then(|subject| subject.title.as_ref()),
80                )]
81            }),
82    );
83
84    println!("{table}", table = table.show());
85}