codeberg-cli 0.5.5

CLI Tool for codeberg similar to gh and glab
Documentation
use crate::render::json::JsonToStdout;
use crate::render::option::option_display;
use crate::{actions::GlobalArgs, types::context::BergContext};
use clap::Parser;
use clap::ValueEnum;
use forgejo_api::structs::{
    Repository, UserCurrentListReposQuery, UserCurrentListReposQueryOrderBy,
};
use miette::IntoDiagnostic;
use strum::{Display, EnumIter, EnumString, IntoStaticStr};

/// List user current active repositories
#[derive(Debug, Parser, Clone, Copy)]
pub struct RepoListArgs {
    /// Order the displayed repositories by different criteria
    #[arg(short, long, value_enum, name = "ORDER BY", default_value_t = OrderBy::Name)]
    pub order_by: OrderBy,
}

#[derive(
    Debug,
    Clone,
    Copy,
    Default,
    PartialEq,
    Eq,
    Display,
    EnumString,
    ValueEnum,
    EnumIter,
    IntoStaticStr,
)]
pub enum OrderBy {
    #[default]
    Name,
    Id,
    Newest,
    Oldest,
    Recentupdate,
    Leastupdate,
    Reversealphabetically,
    Alphabetically,
    Reversesize,
    Size,
    Reversegitsize,
    Gitsize,
    Reverselfssize,
    Lfssize,
    Moststars,
    Feweststars,
    Mostforks,
    Fewestforks,
}

impl From<OrderBy> for UserCurrentListReposQueryOrderBy {
    fn from(value: OrderBy) -> Self {
        match value {
            OrderBy::Name => Self::Name,
            OrderBy::Id => Self::Id,
            OrderBy::Newest => Self::Newest,
            OrderBy::Oldest => Self::Oldest,
            OrderBy::Recentupdate => Self::Recentupdate,
            OrderBy::Leastupdate => Self::Leastupdate,
            OrderBy::Reversealphabetically => Self::Reversealphabetically,
            OrderBy::Alphabetically => Self::Alphabetically,
            OrderBy::Reversesize => Self::Reversesize,
            OrderBy::Size => Self::Size,
            OrderBy::Reversegitsize => Self::Reversegitsize,
            OrderBy::Gitsize => Self::Gitsize,
            OrderBy::Reverselfssize => Self::Reverselfssize,
            OrderBy::Lfssize => Self::Lfssize,
            OrderBy::Moststars => Self::Moststars,
            OrderBy::Feweststars => Self::Feweststars,
            OrderBy::Mostforks => Self::Mostforks,
            OrderBy::Fewestforks => Self::Fewestforks,
        }
    }
}

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

        let (_, repos) = ctx
            .client
            .user_current_list_repos(UserCurrentListReposQuery {
                order_by: Some(ctx.args.order_by.into()),
            })
            .await
            .into_diagnostic()?;

        match ctx.global_args.output_mode {
            crate::types::output::OutputMode::Pretty => {
                present_repos(ctx, repos).await?;
            }
            crate::types::output::OutputMode::Json => {
                repos.print_json()?;
            }
        }

        Ok(())
    }
}

async fn present_repos(
    ctx: BergContext<RepoListArgs>,
    repos: Vec<Repository>,
) -> miette::Result<()> {
    let table = ctx
        .make_table()
        .set_header(vec!["Name", "Description", "Size", "Visibility", "Updated"])
        .add_rows(repos.iter().map(|repo| {
            let Repository {
                name,
                description,
                updated_at,
                private,
                archived,
                fork,
                size,
                ..
            } = repo;

            let repo_visibility = if private.unwrap_or(false) {
                "Private"
            } else {
                "Public"
            };
            let is_archived = archived.unwrap_or(false);
            let is_fork = fork.unwrap_or(false);

            let mut info_arr = vec![repo_visibility];

            if is_archived {
                info_arr.push("Archived");
            }

            if is_fork {
                info_arr.push("Fork");
            }

            vec![
                option_display(name),
                option_display(description),
                option_display(size),
                info_arr.join(", "),
                option_display(updated_at),
            ]
        }));

    println!("{tbl}", tbl = table.show());

    Ok(())
}