fix: all tables respect table_config from settings
Extract shared render_item_info_table() and render_list_table() in modes/common.rs. Update client/info, client/list, client/status, info, status, and status_plugins to use create_table_with_config with settings.table_config instead of hardcoded presets. Previously only local --list used table_config; all other tables (client modes, status, status-plugins) ignored it.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
use crate::client::KeepClient;
|
||||
use crate::modes::common::{OutputFormat, format_size, settings_output_format};
|
||||
use crate::modes::common::{
|
||||
DisplayItemInfo, OutputFormat, format_size, render_item_info_table, settings_output_format,
|
||||
};
|
||||
use clap::Command;
|
||||
use log::debug;
|
||||
|
||||
@@ -36,27 +38,24 @@ pub fn mode(
|
||||
println!("{}", serde_yaml::to_string(&item)?);
|
||||
}
|
||||
OutputFormat::Table => {
|
||||
use comfy_table::{Table, presets::UTF8_FULL};
|
||||
|
||||
let mut table = Table::new();
|
||||
table.load_preset(UTF8_FULL);
|
||||
|
||||
let size_str = item
|
||||
let display = DisplayItemInfo {
|
||||
id: item.id,
|
||||
timestamp: item.ts.clone(),
|
||||
path: String::new(),
|
||||
stream_size: item
|
||||
.size
|
||||
.map(|s| format_size(s as u64, settings.human_readable))
|
||||
.unwrap_or_else(|| "N/A".to_string());
|
||||
|
||||
table.add_row(vec!["ID".to_string(), item.id.to_string()]);
|
||||
table.add_row(vec!["Time".to_string(), item.ts.clone()]);
|
||||
table.add_row(vec!["Size".to_string(), size_str]);
|
||||
table.add_row(vec!["Compression".to_string(), item.compression.clone()]);
|
||||
table.add_row(vec!["Tags".to_string(), item.tags.join(", ")]);
|
||||
|
||||
for (key, value) in &item.metadata {
|
||||
table.add_row(vec![format!("Meta: {}", key), value.clone()]);
|
||||
}
|
||||
|
||||
println!("{table}");
|
||||
.unwrap_or_else(|| "N/A".to_string()),
|
||||
compression: item.compression.clone(),
|
||||
file_size: String::new(),
|
||||
tags: item.tags.clone(),
|
||||
metadata: item
|
||||
.metadata
|
||||
.iter()
|
||||
.map(|(k, v)| (k.clone(), v.clone()))
|
||||
.collect(),
|
||||
};
|
||||
render_item_info_table(&display, &settings.table_config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use crate::client::KeepClient;
|
||||
use crate::modes::common::{OutputFormat, format_size, settings_output_format};
|
||||
use crate::modes::common::{
|
||||
DisplayListItem, OutputFormat, format_size, render_list_table, settings_output_format,
|
||||
};
|
||||
use clap::Command;
|
||||
use log::debug;
|
||||
|
||||
@@ -28,31 +30,20 @@ pub fn mode(
|
||||
println!("{}", serde_yaml::to_string(&items)?);
|
||||
}
|
||||
OutputFormat::Table => {
|
||||
use comfy_table::{Table, presets::UTF8_FULL};
|
||||
|
||||
let mut table = Table::new();
|
||||
table.load_preset(UTF8_FULL);
|
||||
|
||||
// Header
|
||||
let headers = ["ID", "Time", "Size", "Compression", "Tags"];
|
||||
table.set_header(headers.iter().map(|h| h.to_string()).collect::<Vec<_>>());
|
||||
|
||||
for item in &items {
|
||||
let size_str = item
|
||||
let display_items: Vec<DisplayListItem> = items
|
||||
.iter()
|
||||
.map(|item| DisplayListItem {
|
||||
id: item.id,
|
||||
time: item.ts.clone(),
|
||||
size: item
|
||||
.size
|
||||
.map(|s| format_size(s as u64, settings.human_readable))
|
||||
.unwrap_or_default();
|
||||
|
||||
table.add_row(vec![
|
||||
item.id.to_string(),
|
||||
item.ts.clone(),
|
||||
size_str,
|
||||
item.compression.clone(),
|
||||
item.tags.join(", "),
|
||||
]);
|
||||
}
|
||||
|
||||
println!("{table}");
|
||||
.unwrap_or_default(),
|
||||
compression: item.compression.clone(),
|
||||
tags: item.tags.clone(),
|
||||
})
|
||||
.collect();
|
||||
render_list_table(&display_items, &settings.table_config);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ pub fn mode(
|
||||
}
|
||||
OutputFormat::Table => {
|
||||
// Paths
|
||||
let mut path_table = crate::modes::common::create_table(true);
|
||||
let mut path_table =
|
||||
crate::modes::common::create_table_with_config(&settings.table_config);
|
||||
path_table.set_header(vec![
|
||||
Cell::new("Type").add_attribute(Attribute::Bold),
|
||||
Cell::new("Path").add_attribute(Attribute::Bold),
|
||||
@@ -46,7 +47,8 @@ pub fn mode(
|
||||
let mut sorted = configured.clone();
|
||||
sorted.sort_by(|a, b| a.name.cmp(&b.name));
|
||||
|
||||
let mut table = crate::modes::common::create_table(true);
|
||||
let mut table =
|
||||
crate::modes::common::create_table_with_config(&settings.table_config);
|
||||
table.set_header(vec![
|
||||
Cell::new("Plugin Name").add_attribute(Attribute::Bold),
|
||||
Cell::new("Enabled").add_attribute(Attribute::Bold),
|
||||
@@ -68,7 +70,8 @@ pub fn mode(
|
||||
|
||||
// Compression
|
||||
if !status_info.compression.is_empty() {
|
||||
let mut table = crate::modes::common::create_table(true);
|
||||
let mut table =
|
||||
crate::modes::common::create_table_with_config(&settings.table_config);
|
||||
table.set_header(vec![
|
||||
Cell::new("Type").add_attribute(Attribute::Bold),
|
||||
Cell::new("Found").add_attribute(Attribute::Bold),
|
||||
|
||||
@@ -337,26 +337,8 @@ pub fn trim_lines_end(s: &str) -> String {
|
||||
/// let mut table = create_table(true);
|
||||
/// table.add_row(vec!["Header1", "Header2"]);
|
||||
/// ```
|
||||
pub fn create_table(use_styling: bool) -> Table {
|
||||
let mut table = Table::new();
|
||||
table.set_content_arrangement(ContentArrangement::Dynamic);
|
||||
|
||||
if use_styling {
|
||||
if std::io::stdout().is_terminal() {
|
||||
table
|
||||
.load_preset(comfy_table::presets::UTF8_FULL)
|
||||
.apply_modifier(comfy_table::modifiers::UTF8_SOLID_INNER_BORDERS);
|
||||
} else {
|
||||
table.load_preset(comfy_table::presets::ASCII_FULL);
|
||||
}
|
||||
} else {
|
||||
table.load_preset(comfy_table::presets::NOTHING);
|
||||
}
|
||||
|
||||
if !std::io::stdout().is_terminal() {
|
||||
table.force_no_tty();
|
||||
}
|
||||
table
|
||||
pub fn create_table(_use_styling: bool) -> Table {
|
||||
create_table_with_config(&crate::config::TableConfig::default())
|
||||
}
|
||||
|
||||
/// Creates a table configured from application table settings.
|
||||
@@ -447,3 +429,88 @@ pub fn create_table_with_config(table_config: &crate::config::TableConfig) -> Ta
|
||||
|
||||
table
|
||||
}
|
||||
|
||||
/// Display data for a single item's detail view (used by --info).
|
||||
pub struct DisplayItemInfo {
|
||||
pub id: i64,
|
||||
pub timestamp: String,
|
||||
pub path: String,
|
||||
pub stream_size: String,
|
||||
pub compression: String,
|
||||
pub file_size: String,
|
||||
pub tags: Vec<String>,
|
||||
pub metadata: Vec<(String, String)>,
|
||||
}
|
||||
|
||||
/// Display data for a single list row (used by --list).
|
||||
pub struct DisplayListItem {
|
||||
pub id: i64,
|
||||
pub time: String,
|
||||
pub size: String,
|
||||
pub compression: String,
|
||||
pub tags: Vec<String>,
|
||||
}
|
||||
|
||||
/// Renders item detail table. Shared by local and client info modes.
|
||||
pub fn render_item_info_table(info: &DisplayItemInfo, table_config: &config::TableConfig) {
|
||||
use comfy_table::{Attribute, Cell};
|
||||
|
||||
let mut table = create_table_with_config(table_config);
|
||||
|
||||
table.add_row(vec![
|
||||
Cell::new("ID").add_attribute(Attribute::Bold),
|
||||
Cell::new(info.id.to_string()),
|
||||
]);
|
||||
table.add_row(vec![
|
||||
Cell::new("Time").add_attribute(Attribute::Bold),
|
||||
Cell::new(&info.timestamp),
|
||||
]);
|
||||
table.add_row(vec![
|
||||
Cell::new("Size").add_attribute(Attribute::Bold),
|
||||
Cell::new(&info.stream_size),
|
||||
]);
|
||||
table.add_row(vec![
|
||||
Cell::new("Compression").add_attribute(Attribute::Bold),
|
||||
Cell::new(&info.compression),
|
||||
]);
|
||||
table.add_row(vec![
|
||||
Cell::new("Tags").add_attribute(Attribute::Bold),
|
||||
Cell::new(info.tags.join(" ")),
|
||||
]);
|
||||
|
||||
for (key, value) in &info.metadata {
|
||||
table.add_row(vec![
|
||||
Cell::new(format!("Meta: {key}")).add_attribute(Attribute::Bold),
|
||||
Cell::new(value),
|
||||
]);
|
||||
}
|
||||
|
||||
println!("{}", trim_lines_end(&table.trim_fmt()));
|
||||
}
|
||||
|
||||
/// Renders list table. Shared by local and client list modes.
|
||||
pub fn render_list_table(items: &[DisplayListItem], table_config: &config::TableConfig) {
|
||||
use comfy_table::{Attribute, Cell};
|
||||
|
||||
let mut table = create_table_with_config(table_config);
|
||||
|
||||
table.set_header(vec![
|
||||
Cell::new("ID").add_attribute(Attribute::Bold),
|
||||
Cell::new("Time").add_attribute(Attribute::Bold),
|
||||
Cell::new("Size").add_attribute(Attribute::Bold),
|
||||
Cell::new("Compression").add_attribute(Attribute::Bold),
|
||||
Cell::new("Tags").add_attribute(Attribute::Bold),
|
||||
]);
|
||||
|
||||
for item in items {
|
||||
table.add_row(vec![
|
||||
item.id.to_string(),
|
||||
item.time.clone(),
|
||||
item.size.clone(),
|
||||
item.compression.clone(),
|
||||
item.tags.join(" "),
|
||||
]);
|
||||
}
|
||||
|
||||
println!("{}", trim_lines_end(&table.trim_fmt()));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::config;
|
||||
use crate::modes::common::{OutputFormat, format_size};
|
||||
use crate::modes::common::{DisplayItemInfo, OutputFormat, format_size, render_item_info_table};
|
||||
use crate::services::types::ItemWithMeta;
|
||||
use anyhow::{Context, Result, anyhow};
|
||||
use clap::Command;
|
||||
@@ -9,7 +9,6 @@ use std::path::PathBuf;
|
||||
|
||||
use crate::services::item_service::ItemService;
|
||||
use chrono::prelude::*;
|
||||
use comfy_table::{Attribute, Cell};
|
||||
|
||||
/// Displays detailed information about an item or the last item if no ID/tags specified.
|
||||
///
|
||||
@@ -148,73 +147,40 @@ fn show_item(
|
||||
let item_id = item.id.context("Item missing ID")?;
|
||||
let item_tags: Vec<String> = item_with_meta.tags.iter().map(|t| t.name.clone()).collect();
|
||||
|
||||
let mut table = crate::modes::common::create_table(false);
|
||||
|
||||
// Add all the rows
|
||||
table.add_row(vec![
|
||||
Cell::new("ID").add_attribute(Attribute::Bold),
|
||||
Cell::new(item_id.to_string()),
|
||||
]);
|
||||
|
||||
let timestamp_str = item.ts.with_timezone(&Local).format("%F %T %Z").to_string();
|
||||
table.add_row(vec![
|
||||
Cell::new("Timestamp").add_attribute(Attribute::Bold),
|
||||
Cell::new(×tamp_str),
|
||||
]);
|
||||
|
||||
let mut item_path_buf = data_path.clone();
|
||||
item_path_buf.push(item_id.to_string());
|
||||
let path_str = item_path_buf
|
||||
.to_str()
|
||||
.ok_or_else(|| anyhow::anyhow!("non-UTF-8 item path"))?
|
||||
.to_string();
|
||||
table.add_row(vec![
|
||||
Cell::new("Path").add_attribute(Attribute::Bold),
|
||||
Cell::new(&path_str),
|
||||
]);
|
||||
|
||||
let size_str = match item.size {
|
||||
Some(size) => format_size(size as u64, settings.human_readable),
|
||||
None => "Missing".to_string(),
|
||||
};
|
||||
table.add_row(vec![
|
||||
Cell::new("Stream Size").add_attribute(Attribute::Bold),
|
||||
Cell::new(&size_str),
|
||||
]);
|
||||
|
||||
table.add_row(vec![
|
||||
Cell::new("Compression").add_attribute(Attribute::Bold),
|
||||
Cell::new(&item.compression),
|
||||
]);
|
||||
|
||||
let file_size_str = match item_path_buf.metadata() {
|
||||
Ok(metadata) => format_size(metadata.len(), settings.human_readable),
|
||||
Err(_) => "Missing".to_string(),
|
||||
};
|
||||
table.add_row(vec![
|
||||
Cell::new("File Size").add_attribute(Attribute::Bold),
|
||||
Cell::new(&file_size_str),
|
||||
]);
|
||||
|
||||
let tags_str = item_tags.join(" ");
|
||||
table.add_row(vec![
|
||||
Cell::new("Tags").add_attribute(Attribute::Bold),
|
||||
Cell::new(&tags_str),
|
||||
]);
|
||||
let metadata: Vec<(String, String)> = item_with_meta
|
||||
.meta
|
||||
.iter()
|
||||
.map(|m| (m.name.clone(), m.value.clone()))
|
||||
.collect();
|
||||
|
||||
// Add meta rows
|
||||
for meta in item_with_meta.meta {
|
||||
let meta_name = format!("Meta: {}", &meta.name);
|
||||
table.add_row(vec![
|
||||
Cell::new(&meta_name).add_attribute(Attribute::Bold),
|
||||
Cell::new(&meta.value),
|
||||
]);
|
||||
}
|
||||
let display = DisplayItemInfo {
|
||||
id: item_id,
|
||||
timestamp: item.ts.with_timezone(&Local).format("%F %T %Z").to_string(),
|
||||
path: item_path_buf
|
||||
.to_str()
|
||||
.ok_or_else(|| anyhow::anyhow!("non-UTF-8 item path"))?
|
||||
.to_string(),
|
||||
stream_size: size_str,
|
||||
compression: item.compression.clone(),
|
||||
file_size: file_size_str,
|
||||
tags: item_tags,
|
||||
metadata,
|
||||
};
|
||||
|
||||
println!(
|
||||
"{}",
|
||||
crate::modes::common::trim_lines_end(&table.trim_fmt())
|
||||
);
|
||||
render_item_info_table(&display, &settings.table_config);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ use crate::common::status::PathInfo;
|
||||
use crate::meta_plugin::MetaPluginType;
|
||||
use crate::meta_plugin::get_meta_plugin;
|
||||
|
||||
fn build_path_table(path_info: &PathInfo) -> Table {
|
||||
let mut path_table = crate::modes::common::create_table(true);
|
||||
fn build_path_table(path_info: &PathInfo, table_config: &config::TableConfig) -> Table {
|
||||
let mut path_table = crate::modes::common::create_table_with_config(table_config);
|
||||
|
||||
path_table.set_header(vec![
|
||||
Cell::new("Type").add_attribute(Attribute::Bold),
|
||||
@@ -29,7 +29,7 @@ fn build_path_table(path_info: &PathInfo) -> Table {
|
||||
}
|
||||
|
||||
fn build_config_table(settings: &config::Settings) -> Table {
|
||||
let mut config_table = crate::modes::common::create_table(true);
|
||||
let mut config_table = crate::modes::common::create_table_with_config(&settings.table_config);
|
||||
|
||||
config_table.set_header(vec![
|
||||
Cell::new("Setting").add_attribute(Attribute::Bold),
|
||||
@@ -52,7 +52,10 @@ fn build_config_table(settings: &config::Settings) -> Table {
|
||||
config_table
|
||||
}
|
||||
|
||||
fn build_meta_plugins_configured_table(status_info: &StatusInfo) -> Option<Table> {
|
||||
fn build_meta_plugins_configured_table(
|
||||
status_info: &StatusInfo,
|
||||
table_config: &config::TableConfig,
|
||||
) -> Option<Table> {
|
||||
let meta_plugins = status_info.configured_meta_plugins.as_ref()?;
|
||||
if meta_plugins.is_empty() {
|
||||
return None;
|
||||
@@ -62,7 +65,7 @@ fn build_meta_plugins_configured_table(status_info: &StatusInfo) -> Option<Table
|
||||
let mut sorted_meta_plugins = meta_plugins.clone();
|
||||
sorted_meta_plugins.sort_by(|a, b| a.name.cmp(&b.name));
|
||||
|
||||
let mut table = crate::modes::common::create_table(true);
|
||||
let mut table = crate::modes::common::create_table_with_config(table_config);
|
||||
|
||||
table.set_header(vec![
|
||||
Cell::new("Plugin Name").add_attribute(Attribute::Bold),
|
||||
@@ -212,7 +215,7 @@ pub fn mode_status(
|
||||
println!();
|
||||
|
||||
println!("PATHS:");
|
||||
let path_table = build_path_table(&status_info.paths);
|
||||
let path_table = build_path_table(&status_info.paths, &settings.table_config);
|
||||
println!(
|
||||
"{}",
|
||||
crate::modes::common::trim_lines_end(&path_table.trim_fmt())
|
||||
@@ -220,7 +223,9 @@ pub fn mode_status(
|
||||
println!();
|
||||
|
||||
// Always try to print META PLUGINS CONFIGURED section using status_info
|
||||
if let Some(meta_plugins_table) = build_meta_plugins_configured_table(&status_info) {
|
||||
if let Some(meta_plugins_table) =
|
||||
build_meta_plugins_configured_table(&status_info, &settings.table_config)
|
||||
{
|
||||
println!("META PLUGINS CONFIGURED:");
|
||||
println!(
|
||||
"{}",
|
||||
|
||||
@@ -60,6 +60,7 @@ use crate::meta_plugin::{MetaPluginType, get_meta_plugin};
|
||||
|
||||
fn build_meta_plugin_table(
|
||||
meta_plugin_info: &std::collections::HashMap<String, MetaPluginInfo>,
|
||||
table_config: &crate::config::TableConfig,
|
||||
) -> Table {
|
||||
// Builds a formatted table displaying meta plugin information.
|
||||
//
|
||||
@@ -72,7 +73,7 @@ fn build_meta_plugin_table(
|
||||
// # Returns
|
||||
//
|
||||
// A formatted `comfy_table::Table`.
|
||||
let mut meta_plugin_table = crate::modes::common::create_table(true);
|
||||
let mut meta_plugin_table = crate::modes::common::create_table_with_config(table_config);
|
||||
|
||||
meta_plugin_table.set_header(vec![
|
||||
Cell::new("Plugin Name").add_attribute(Attribute::Bold),
|
||||
@@ -126,7 +127,10 @@ fn build_meta_plugin_table(
|
||||
meta_plugin_table
|
||||
}
|
||||
|
||||
fn build_compression_table(compression_info: &Vec<CompressionInfo>) -> Table {
|
||||
fn build_compression_table(
|
||||
compression_info: &Vec<CompressionInfo>,
|
||||
table_config: &crate::config::TableConfig,
|
||||
) -> Table {
|
||||
// Builds a formatted table displaying compression plugin information.
|
||||
//
|
||||
// # Arguments
|
||||
@@ -136,7 +140,7 @@ fn build_compression_table(compression_info: &Vec<CompressionInfo>) -> Table {
|
||||
// # Returns
|
||||
//
|
||||
// A formatted `comfy_table::Table`.
|
||||
let mut compression_table = crate::modes::common::create_table(true);
|
||||
let mut compression_table = crate::modes::common::create_table_with_config(table_config);
|
||||
|
||||
compression_table.set_header(vec![
|
||||
Cell::new("Type").add_attribute(Attribute::Bold),
|
||||
@@ -167,7 +171,10 @@ fn build_compression_table(compression_info: &Vec<CompressionInfo>) -> Table {
|
||||
compression_table
|
||||
}
|
||||
|
||||
fn build_filter_plugin_table(filter_plugins: &[crate::common::status::FilterPluginInfo]) -> Table {
|
||||
fn build_filter_plugin_table(
|
||||
filter_plugins: &[crate::common::status::FilterPluginInfo],
|
||||
table_config: &crate::config::TableConfig,
|
||||
) -> Table {
|
||||
// Builds a formatted table displaying filter plugin information.
|
||||
//
|
||||
// Sorts plugins by name and formats options as YAML sequence.
|
||||
@@ -179,7 +186,7 @@ fn build_filter_plugin_table(filter_plugins: &[crate::common::status::FilterPlug
|
||||
// # Returns
|
||||
//
|
||||
// A formatted `comfy_table::Table`.
|
||||
let mut filter_plugin_table = crate::modes::common::create_table(true);
|
||||
let mut filter_plugin_table = crate::modes::common::create_table_with_config(table_config);
|
||||
|
||||
filter_plugin_table.set_header(vec![
|
||||
Cell::new("Plugin Name").add_attribute(Attribute::Bold),
|
||||
@@ -304,7 +311,8 @@ pub fn mode_status_plugins(
|
||||
match output_format {
|
||||
OutputFormat::Table => {
|
||||
println!("META PLUGINS:");
|
||||
let meta_table = build_meta_plugin_table(&status_info.meta_plugins);
|
||||
let meta_table =
|
||||
build_meta_plugin_table(&status_info.meta_plugins, &settings.table_config);
|
||||
println!(
|
||||
"{}",
|
||||
crate::modes::common::trim_lines_end(&meta_table.trim_fmt())
|
||||
@@ -312,7 +320,8 @@ pub fn mode_status_plugins(
|
||||
println!();
|
||||
|
||||
println!("COMPRESSION PLUGINS:");
|
||||
let compression_table = build_compression_table(&status_info.compression);
|
||||
let compression_table =
|
||||
build_compression_table(&status_info.compression, &settings.table_config);
|
||||
println!(
|
||||
"{}",
|
||||
crate::modes::common::trim_lines_end(&compression_table.trim_fmt())
|
||||
@@ -320,7 +329,8 @@ pub fn mode_status_plugins(
|
||||
println!();
|
||||
|
||||
println!("FILTER PLUGINS:");
|
||||
let filter_table = build_filter_plugin_table(&status_info.filter_plugins);
|
||||
let filter_table =
|
||||
build_filter_plugin_table(&status_info.filter_plugins, &settings.table_config);
|
||||
println!(
|
||||
"{}",
|
||||
crate::modes::common::trim_lines_end(&filter_table.trim_fmt())
|
||||
|
||||
Reference in New Issue
Block a user