use chrono::{DateTime, Local};
use comfy_table::Table;
use manta_shared::types::dto::CfsConfigurationResponse;
use manta_shared::common::DATETIME_FORMAT;
pub fn print_table_struct(rows: &[(CfsConfigurationResponse, bool)]) {
let mut table = Table::new();
table.set_header(vec![
"Config Name",
"Last updated",
"Layers",
"Safe to delete",
]);
for (cfs_configuration, safe_to_delete) in rows {
let mut layers: String = String::new();
if let Some(first_layer) = cfs_configuration.layers.first() {
let layers_json = &cfs_configuration.layers;
layers = format!(
"Name: {}\nPlaybook: {}\nCommit: {}",
first_layer.name.as_ref().unwrap_or(&String::new()),
first_layer.playbook,
first_layer.commit.as_deref().unwrap_or("Not defined"),
);
for layer in layers_json.iter().skip(1) {
layers = format!(
"{}\n\nName: {}\nPlaybook: {}\nCommit: {}",
layers,
layer.name.as_ref().unwrap_or(&String::new()),
layer.playbook,
layer.commit.as_deref().unwrap_or("Not defined"),
);
}
}
table.add_row(vec![
cfs_configuration.name.clone(),
cfs_configuration
.last_updated
.clone()
.parse::<DateTime<Local>>()
.map_or_else(
|_| cfs_configuration.last_updated.clone(),
|dt| dt.format(DATETIME_FORMAT).to_string(),
),
layers,
if *safe_to_delete { "yes" } else { "no" }.to_string(),
]);
}
println!("{table}");
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
fn from_json(value: serde_json::Value) -> CfsConfigurationResponse {
serde_json::from_value(value).unwrap()
}
#[test]
fn print_empty_list_does_not_panic() {
print_table_struct(&[]);
}
#[test]
fn print_config_with_no_layers_does_not_panic() {
let cfg = from_json(json!({
"name": "cfg-empty",
"last_updated": "2026-06-04T12:00:00Z",
"layers": [],
}));
print_table_struct(&[(cfg, true)]);
}
#[test]
fn print_config_with_single_layer_does_not_panic() {
let cfg = from_json(json!({
"name": "cfg-one",
"last_updated": "2026-06-04T12:00:00Z",
"layers": [{
"name": "ss11",
"clone_url": "https://example.com/repo.git",
"playbook": "site.yml",
"commit": "abc123",
}],
}));
print_table_struct(&[(cfg, true)]);
}
#[test]
fn print_config_with_multiple_layers_does_not_panic() {
let cfg = from_json(json!({
"name": "cfg-multi",
"last_updated": "2026-06-04T12:00:00Z",
"layers": [
{"name": "ss11", "clone_url": "https://x", "playbook": "a.yml", "commit": "abc"},
{"clone_url": "https://y", "playbook": "b.yml"},
{"name": "cscs", "clone_url": "https://z", "playbook": "c.yml", "commit": "def"},
],
}));
print_table_struct(&[(cfg, false)]);
}
#[test]
fn print_config_with_unparseable_date_falls_back_to_raw_string() {
let cfg = from_json(json!({
"name": "cfg-bad-date",
"last_updated": "not-a-real-date",
"layers": [],
}));
print_table_struct(&[(cfg, true)]);
}
}