bb_cli/commands/
project.rs1use crate::api::models::Project;
2use crate::error::Result;
3use crate::output::{self, Format};
4use crate::workspace::{self, WorkspaceCtx};
5use serde::Serialize;
6
7#[derive(Debug, Serialize)]
8struct ProjectRow {
9 key: String,
10 name: String,
11 access: String,
12}
13
14fn rows(projects: &[Project], name: Option<String>, limit: usize) -> Vec<ProjectRow> {
15 let needle = name.map(|n| n.to_lowercase());
16 projects
17 .iter()
18 .filter(|p| match &needle {
19 Some(needle) => {
20 p.name_or_dash().to_lowercase().contains(needle)
21 || p.key_or_dash().to_lowercase().contains(needle)
22 }
23 None => true,
24 })
25 .take(limit)
26 .map(|p| ProjectRow {
27 key: p.key_or_dash().to_string(),
28 name: p.name_or_dash().to_string(),
29 access: p.access().to_string(),
30 })
31 .collect()
32}
33
34pub async fn list(ctx: &WorkspaceCtx, name: Option<String>, limit: usize) -> Result<()> {
35 let spinner = output::spinner("fetching projects");
36 let projects = workspace::projects(ctx).await?;
37 spinner.finish_and_clear();
38
39 let rows = rows(&projects, name, limit);
40
41 match ctx.format {
42 Format::Json => output::print_json(&rows)?,
43 Format::Human => output::print_table(
44 &["KEY", "NAME", "ACCESS"],
45 rows.iter()
46 .map(|r| vec![r.key.clone(), r.name.clone(), r.access.clone()])
47 .collect(),
48 ),
49 }
50 Ok(())
51}