codeberg-cli 0.5.5

CLI Tool for codeberg similar to gh and glab
Documentation
use forgejo_api::structs::UserCurrentListReposQuery;
use itertools::Itertools;
use miette::IntoDiagnostic;

use crate::actions::GlobalArgs;
use crate::render::json::JsonToStdout;
use crate::render::option::option_display;
use crate::render::spinner::spin_until_ready;
use crate::types::context::BergContext;
use crate::types::output::OutputMode;

use clap::Parser;

/// Display short summary of the authenticated user account
#[derive(Parser, Debug)]
pub struct UserInfoArgs {}

impl UserInfoArgs {
    pub async fn run(self, global_args: GlobalArgs) -> miette::Result<()> {
        let ctx = BergContext::new(self, global_args).await?;

        present_user_info(&ctx).await?;
        Ok(())
    }
}

async fn present_user_info(ctx: &BergContext<UserInfoArgs>) -> miette::Result<()> {
    let user = spin_until_ready(ctx.client.user_get_current().send())
        .await
        .into_diagnostic()?;
    let (_, repos) = ctx
        .client
        .user_current_list_repos(UserCurrentListReposQuery::default())
        .await
        .into_diagnostic()?;
    let top_repos = repos
        .iter()
        .sorted_by_key(|repo| repo.stars_count.unwrap_or_default())
        .rev()
        .take(5)
        .collect::<Vec<_>>();

    match ctx.global_args.output_mode {
        OutputMode::Pretty => {
            let table = ctx
                .make_table()
                .set_header(vec!["User Information"])
                .add_row(vec![String::from("Username"), option_display(&user.login)])
                .add_row(vec![
                    String::from("Followers"),
                    option_display(&user.followers_count),
                ])
                .add_row(vec![
                    String::from("Following"),
                    option_display(&user.following_count),
                ])
                .add_row(vec![String::from("Repos"), repos.len().to_string()])
                .add_row(vec![
                    String::from("Top Repos"),
                    top_repos
                        .into_iter()
                        .map(|repo| {
                            format!(
                                "{}({}★)",
                                option_display(&repo.name),
                                option_display(&repo.stars_count)
                            )
                        })
                        .join(", "),
                ]);

            println!("{table}", table = table.show());
        }
        OutputMode::Json => {
            user.print_json()?;
        }
    }

    Ok(())
}