diff --git a/module/core/format_tools/src/format/output_format/table.rs b/module/core/format_tools/src/format/output_format/table.rs index e96af36f20..59e69cfc3b 100644 --- a/module/core/format_tools/src/format/output_format/table.rs +++ b/module/core/format_tools/src/format/output_format/table.rs @@ -75,6 +75,8 @@ pub struct Table pub corner_lb : char, /// Bottom-right corner character. pub corner_rb : char, + /// Limit table size (0 - no limit). + pub max_width : usize, } impl Default for Table @@ -103,6 +105,8 @@ impl Default for Table let corner_lb = '└'; let corner_rb = '┘'; + let max_width = 50; + Self { delimitting_header, @@ -123,6 +127,7 @@ impl Default for Table corner_rt, corner_lb, corner_rb, + max_width, } } } @@ -192,6 +197,17 @@ impl TableOutputFormat for Table // dbg!( x.row_descriptors.len() ); + let table_width: usize = x.col_descriptors.iter().map( |col| col.width ).sum(); + + let shrink_factor = if self.max_width == 0 || table_width <= self.max_width + { + 1.0 + } + else + { + ( self.max_width as f32 ) / ( table_width as f32 ) + }; + for ( irow, row ) in x.row_descriptors.iter().enumerate() { let height = row.height; @@ -203,7 +219,8 @@ impl TableOutputFormat for Table if prev_typ == LineType::Header && row.typ == LineType::Regular { write!( c.buf, "{}", row_separator )?; - write!( c.buf, "{}", h.repeat( row_width ) )?; + let new_row_width = ( ( row_width as f32 ) * shrink_factor ).floor() as usize; + write!( c.buf, "{}", h.repeat( new_row_width ) )?; delimitting_header = false } } @@ -234,7 +251,7 @@ impl TableOutputFormat for Table { let col = &x.col_descriptors[ icol ]; let cell_width = x.data[ irow ][ icol ].1[0]; - let width = col.width; + let width = ( ( col.width as f32 ) * shrink_factor ).floor() as usize; let md_index = [ islice, icol, irow as usize ]; let slice = x.slices[ x.slices_dim.md_offset( md_index ) ]; @@ -247,7 +264,7 @@ impl TableOutputFormat for Table write!( c.buf, "{}", cell_prefix )?; - println!( "icol : {icol} | irow : {irow} | width : {width} | cell_width : {cell_width} | slice.len() : {}", slice.len() ); + // println!( "icol : {icol} | irow : {irow} | width : {width} | cell_width : {cell_width} | slice.len() : {}", slice.len() ); let lspaces = if cell_width > width { 0 diff --git a/module/move/assistant/src/actions/openai_assistants_list.rs b/module/move/assistant/src/actions/openai_assistants_list.rs index 9859761c3b..75333a645a 100644 --- a/module/move/assistant/src/actions/openai_assistants_list.rs +++ b/module/move/assistant/src/actions/openai_assistants_list.rs @@ -18,13 +18,14 @@ mod private use client::Client; use debug::AssistantObjectWrap; use actions::openai::Result; + use commands::TableConfig; /// Report for `openai assistants list`. #[ derive( Debug ) ] pub struct ListReport { - /// Show records as separate tables. - pub show_records_as_tables : bool, + /// Table config of the report. + pub table_config : TableConfig, /// OpenAI assistants. pub assistants: Vec< AssistantObjectWrap > @@ -38,7 +39,7 @@ mod private f : &mut fmt::Formatter< '_ > ) -> fmt::Result { - if self.show_records_as_tables + if self.table_config.as_records { writeln!(f, "{}", AsTable::new( &self.assistants ).table_to_string_with_format( &output_format::Records::default() ) ) } @@ -53,12 +54,12 @@ mod private pub async fn action ( client : &Client, - show_records_as_tables : bool, + table_config : TableConfig, ) -> Result < ListReport > { let response = client.list_assistant( None, None, None, None ).await?; let assistants = response.data.into_iter().map( AssistantObjectWrap ).collect(); - Ok( ListReport { show_records_as_tables, assistants } ) + Ok( ListReport { table_config, assistants } ) } } diff --git a/module/move/assistant/src/actions/openai_files_list.rs b/module/move/assistant/src/actions/openai_files_list.rs index 8a3f371a92..fafbdf24dc 100644 --- a/module/move/assistant/src/actions/openai_files_list.rs +++ b/module/move/assistant/src/actions/openai_files_list.rs @@ -18,13 +18,14 @@ mod private use client::Client; use debug::FileDataWrap; use actions::openai::Result; + use commands::TableConfig; /// Report for `openai files list`. #[ derive( Debug ) ] pub struct ListReport { - /// Show records as separate tables. - pub show_records_as_tables : bool, + /// Table config of the report. + pub table_config : TableConfig, /// Files in OpenAI. pub files : Vec< FileDataWrap > @@ -38,7 +39,7 @@ mod private f : &mut fmt::Formatter< '_ > ) -> fmt::Result { - if self.show_records_as_tables + if self.table_config.as_records { writeln!(f, "{}", AsTable::new( &self.files ).table_to_string_with_format( &output_format::Records::default() ) ) } @@ -53,12 +54,12 @@ mod private pub async fn action ( client : &Client, - show_records_as_tables : bool, + table_config : TableConfig, ) -> Result < ListReport > { let response = client.file_list().await?; let files = response.data.into_iter().map( FileDataWrap ).collect(); - Ok( ListReport { show_records_as_tables, files } ) + Ok( ListReport { table_config, files } ) } } diff --git a/module/move/assistant/src/actions/openai_runs_list.rs b/module/move/assistant/src/actions/openai_runs_list.rs index 631b6ed4cb..d4f1753bf8 100644 --- a/module/move/assistant/src/actions/openai_runs_list.rs +++ b/module/move/assistant/src/actions/openai_runs_list.rs @@ -18,13 +18,14 @@ mod private use client::Client; use debug::RunObjectWrap; use actions::openai::Result; + use commands::TableConfig; /// Report for `openai runs list`. #[ derive( Debug ) ] pub struct ListReport { - /// Show records as separate tables. - pub show_records_as_tables : bool, + /// Table config of the report. + pub table_config : TableConfig, /// Current OpenAI runs. pub runs : Vec< RunObjectWrap > @@ -38,7 +39,7 @@ mod private f : &mut fmt::Formatter< '_ > ) -> fmt::Result { - if self.show_records_as_tables + if self.table_config.as_records { writeln!(f, "{}", AsTable::new( &self.runs ).table_to_string_with_format( &output_format::Records::default() ) ) } @@ -54,12 +55,12 @@ mod private ( client : &Client, thread_id : String, - show_records_as_tables : bool, + table_config : TableConfig, ) -> Result < ListReport > { let response = client.list_run( thread_id, None, None, None, None ).await?; let runs = response.data.into_iter().map( RunObjectWrap ).collect(); - Ok( ListReport { show_records_as_tables, runs } ) + Ok( ListReport { table_config, runs } ) } } diff --git a/module/move/assistant/src/bin/main.rs b/module/move/assistant/src/bin/main.rs index adeeaf150f..3887c3d200 100644 --- a/module/move/assistant/src/bin/main.rs +++ b/module/move/assistant/src/bin/main.rs @@ -12,31 +12,16 @@ use std:: use dotenv::dotenv; use clap::Parser; -use assistant:: -{ - client::client, - commands::{ Cli, CliCommand, self }, - Secret -}; +use assistant::commands::{ Cli, self }; #[ tokio::main ] async fn main() -> Result< (), Box< dyn Error > > { dotenv().ok(); - let secret = Secret::load()?; - - let client = client::client( &secret )?; - let cli = Cli::parse(); - match cli.command - { - CliCommand::OpenAi( openai_command ) => - { - commands::openai::command( &client, openai_command ).await; - } - } + commands::execute(cli).await?; Ok( () ) } diff --git a/module/move/assistant/src/commands.rs b/module/move/assistant/src/commands.rs index 7a8f56c76c..5574da9e9c 100644 --- a/module/move/assistant/src/commands.rs +++ b/module/move/assistant/src/commands.rs @@ -6,6 +6,8 @@ mod private { + use std::error::Error; + use clap::{ Parser, Subcommand }; use crate::*; @@ -17,7 +19,26 @@ mod private { /// Root of the CLI commands. #[ command ( subcommand ) ] - pub command : CliCommand, + pub subcommand : CliCommand, + + /// Table view configuration. + #[ command ( flatten ) ] + pub table_config : TableConfig, + } + + const DEFAULT_MAX_TABLE_WIDTH: usize = 130; + + /// Table view configuration. + #[ derive( Debug, Parser ) ] + pub struct TableConfig + { + /// Show records as separate tables. + #[ arg( long, default_value_t = false ) ] + pub as_records : bool, + + /// Limit table width. + #[ arg( long, default_value_t = DEFAULT_MAX_TABLE_WIDTH ) ] + pub max_table_width : usize, } /// Root of the CLI commands. @@ -29,6 +50,24 @@ mod private OpenAi( openai::Command ), } + /// Execute CLI command. + pub async fn execute( command : Cli ) -> Result< (), Box< dyn Error > > + { + let secret = Secret::load()?; + + let client = client::client( &secret )?; + + match command.subcommand + { + CliCommand::OpenAi( openai_command ) => + { + commands::openai::command( &client, openai_command, command.table_config ).await; + } + } + + Ok( () ) + } + } crate::mod_interface! @@ -45,5 +84,7 @@ crate::mod_interface! { Cli, CliCommand, + TableConfig, + execute, }; } diff --git a/module/move/assistant/src/commands/openai.rs b/module/move/assistant/src/commands/openai.rs index 42c7ea5595..df3704df3a 100644 --- a/module/move/assistant/src/commands/openai.rs +++ b/module/move/assistant/src/commands/openai.rs @@ -9,7 +9,7 @@ mod private use crate::*; use client::Client; - use commands::{ openai_assistants, openai_files, openai_runs }; + use commands::{ openai_assistants, openai_files, openai_runs, TableConfig }; /// OpenAI API commands. #[ derive ( Debug, Subcommand ) ] @@ -42,23 +42,24 @@ mod private ( client : &Client, command : Command, + table_config : TableConfig, ) { match command { Command::Assistants( assistants_command ) => { - openai_assistants::command( client, assistants_command ).await; + openai_assistants::command( client, assistants_command, table_config ).await; } Command::Files( files_command ) => { - openai_files::command( client, files_command ).await; + openai_files::command( client, files_command, table_config ).await; } Command::Runs( runs_command ) => { - openai_runs::command( client, runs_command ).await; + openai_runs::command( client, runs_command, table_config ).await; } } } diff --git a/module/move/assistant/src/commands/openai_assistants.rs b/module/move/assistant/src/commands/openai_assistants.rs index 66e2d057e8..7926d29130 100644 --- a/module/move/assistant/src/commands/openai_assistants.rs +++ b/module/move/assistant/src/commands/openai_assistants.rs @@ -9,19 +9,14 @@ mod private use crate::*; use client::Client; - use commands::openai_assistants_list; + use commands::{ openai_assistants_list, TableConfig }; /// OpenAI assistants. #[ derive ( Debug, Subcommand ) ] pub enum Command { /// List OpenAI assistants. - List - { - /// Show records as separate tables. - #[ arg( long, default_value_t = false ) ] - show_records_as_tables : bool - }, + List, } /// Execute OpenAI command related to assistants. @@ -29,13 +24,14 @@ mod private ( client : &Client, command : Command, + table_config : TableConfig, ) { match command { - Command::List{ show_records_as_tables } => + Command::List => { - openai_assistants_list::command( client, show_records_as_tables ).await; + openai_assistants_list::command( client, table_config ).await; } } } diff --git a/module/move/assistant/src/commands/openai_assistants_list.rs b/module/move/assistant/src/commands/openai_assistants_list.rs index 95e1ffb62c..6ce7a80ac4 100644 --- a/module/move/assistant/src/commands/openai_assistants_list.rs +++ b/module/move/assistant/src/commands/openai_assistants_list.rs @@ -8,15 +8,16 @@ mod private use crate::*; use client::Client; use actions; + use commands::TableConfig; /// List OpenAI assistants command. pub async fn command ( client : &Client, - show_records_as_tables : bool, + table_config : TableConfig, ) { - let result = actions::openai_assistants_list::action( client, show_records_as_tables ).await; + let result = actions::openai_assistants_list::action( client, table_config ).await; match result { diff --git a/module/move/assistant/src/commands/openai_files.rs b/module/move/assistant/src/commands/openai_files.rs index 33e18fea0a..47864ddb75 100644 --- a/module/move/assistant/src/commands/openai_files.rs +++ b/module/move/assistant/src/commands/openai_files.rs @@ -9,19 +9,14 @@ mod private use crate::*; use client::Client; - use commands::openai_files_list; + use commands::{ openai_files_list, TableConfig }; /// OpenAI files. #[ derive ( Debug, Subcommand ) ] pub enum Command { /// List OpenAI files. - List - { - /// Show records as separate tables. - #[ arg( long, default_value_t = false ) ] - show_records_as_tables : bool - }, + List, } /// Execute OpenAI commands related to files. @@ -29,13 +24,14 @@ mod private ( client : &Client, command : Command, + table_config : TableConfig, ) { match command { - Command::List{ show_records_as_tables } => + Command::List => { - openai_files_list::command( client, show_records_as_tables ).await; + openai_files_list::command( client, table_config ).await; } } } diff --git a/module/move/assistant/src/commands/openai_files_list.rs b/module/move/assistant/src/commands/openai_files_list.rs index 04bc83c0c4..6225b9faf2 100644 --- a/module/move/assistant/src/commands/openai_files_list.rs +++ b/module/move/assistant/src/commands/openai_files_list.rs @@ -8,15 +8,16 @@ mod private use crate::*; use client::Client; use actions; + use commands::TableConfig; /// List files in your OpenAI API. pub async fn command ( client : &Client, - show_records_as_tables : bool, + table_config : TableConfig, ) { - let result = actions::openai_files_list::action( client, show_records_as_tables ).await; + let result = actions::openai_files_list::action( client, table_config ).await; match result { diff --git a/module/move/assistant/src/commands/openai_runs.rs b/module/move/assistant/src/commands/openai_runs.rs index e5e183b33e..241dce4a97 100644 --- a/module/move/assistant/src/commands/openai_runs.rs +++ b/module/move/assistant/src/commands/openai_runs.rs @@ -9,7 +9,7 @@ mod private use crate::*; use client::Client; - use commands::openai_runs_list; + use commands::{ openai_runs_list, TableConfig }; /// OpenAI runs. #[ derive ( Debug, Subcommand ) ] @@ -20,10 +20,6 @@ mod private { /// Thread ID. thread_id : String, - - /// Show records as separate tables. - #[ arg( long, default_value_t = false ) ] - show_records_as_tables : bool }, } @@ -32,13 +28,14 @@ mod private ( client : &Client, command : Command, + table_config : TableConfig, ) { match command { - Command::List { thread_id, show_records_as_tables } => + Command::List { thread_id } => { - openai_runs_list::command( client, thread_id, show_records_as_tables ).await; + openai_runs_list::command( client, thread_id, table_config ).await; } } } diff --git a/module/move/assistant/src/commands/openai_runs_list.rs b/module/move/assistant/src/commands/openai_runs_list.rs index 928e0b473a..6d08d64ed3 100644 --- a/module/move/assistant/src/commands/openai_runs_list.rs +++ b/module/move/assistant/src/commands/openai_runs_list.rs @@ -8,16 +8,17 @@ mod private use crate::*; use client::Client; use actions; + use commands::TableConfig; /// List runs in the thread in OpenAI API. pub async fn command ( client : &Client, thread_id : String, - show_records_as_tables : bool, + table_config : TableConfig, ) { - let result = actions::openai_runs_list::action( client, thread_id, show_records_as_tables ).await; + let result = actions::openai_runs_list::action( client, thread_id, table_config ).await; match result {