Skip to main content

cellos_ctl/cmd/
get.rs

1//! `cellctl get formations` / `cellctl get cells` — list resources.
2//!
3//! Each subcommand corresponds to **exactly one** HTTP GET (Feynman's rule from
4//! CHATROOM Session 16). Filters that the server understands (`?formation=`) are
5//! forwarded as query params; nothing is filtered client-side.
6
7use crate::client::CellosClient;
8use crate::exit::CtlResult;
9use crate::model::{CellsSnapshot, FormationsSnapshot};
10use crate::output::{self, OutputFormat};
11
12pub async fn formations(client: &CellosClient, fmt: OutputFormat) -> CtlResult<()> {
13    // MED-CTL-001-A: typed snapshot per endpoint; previously this used a
14    // generic `List<T>` whose `formations`/`cells`/`items` alias collapse
15    // could silently drop half a mixed envelope.
16    let snap: FormationsSnapshot = client.get_json("/v1/formations").await?;
17    output::render_formations(&snap.formations, fmt);
18    Ok(())
19}
20
21pub async fn cells(
22    client: &CellosClient,
23    formation: Option<&str>,
24    fmt: OutputFormat,
25) -> CtlResult<()> {
26    let path = match formation {
27        Some(f) => format!("/v1/cells?formation={}", urlencode(f)),
28        None => "/v1/cells".to_string(),
29    };
30    let snap: CellsSnapshot = client.get_json(&path).await?;
31    output::render_cells(&snap.cells, fmt);
32    Ok(())
33}
34
35fn urlencode(s: &str) -> String {
36    percent_encoding::utf8_percent_encode(s, percent_encoding::NON_ALPHANUMERIC).collect()
37}