From 8bc969dfe9c1547852a20048fee2195f11fba79d Mon Sep 17 00:00:00 2001 From: "alex.kopachov" Date: Fri, 25 Aug 2023 15:32:03 +0200 Subject: [PATCH] Implemented #193 --- totp/cli/cli.c | 2 +- totp/cli/commands/details/details.c | 85 +++++++++++++------ .../table/details_output_formatter_table.c | 32 +++++++ .../table/details_output_formatter_table.h | 12 +++ .../tsv/details_output_formatter_tsv.c | 29 +++++++ .../tsv/details_output_formatter_tsv.h | 12 +++ .../table/list_output_formatter_table.c | 22 +++++ .../table/list_output_formatter_table.h | 9 ++ .../tsv/list_output_formatter_tsv.c | 19 +++++ .../tsv/list_output_formatter_tsv.h | 9 ++ totp/cli/commands/list/list.c | 47 +++++++--- totp/cli/commands/list/list.h | 2 +- 12 files changed, 238 insertions(+), 42 deletions(-) create mode 100644 totp/cli/commands/details/formatters/table/details_output_formatter_table.c create mode 100644 totp/cli/commands/details/formatters/table/details_output_formatter_table.h create mode 100644 totp/cli/commands/details/formatters/tsv/details_output_formatter_tsv.c create mode 100644 totp/cli/commands/details/formatters/tsv/details_output_formatter_tsv.h create mode 100644 totp/cli/commands/list/formatters/table/list_output_formatter_table.c create mode 100644 totp/cli/commands/list/formatters/table/list_output_formatter_table.h create mode 100644 totp/cli/commands/list/formatters/tsv/list_output_formatter_tsv.c create mode 100644 totp/cli/commands/list/formatters/tsv/list_output_formatter_tsv.h diff --git a/totp/cli/cli.c b/totp/cli/cli.c index 4cb68ce8320..a556c31acfa 100644 --- a/totp/cli/cli.c +++ b/totp/cli/cli.c @@ -47,7 +47,7 @@ static void totp_cli_handler(Cli* cli, FuriString* args, void* context) { } else if( furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_LIST) == 0 || furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_LIST_ALT) == 0) { - totp_cli_command_list_handle(plugin_state, cli); + totp_cli_command_list_handle(plugin_state, args, cli); } else if( furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_DELETE) == 0 || furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_DELETE_ALT) == 0) { diff --git a/totp/cli/commands/details/details.c b/totp/cli/commands/details/details.c index 7e714bf6995..29a53d7eeb6 100644 --- a/totp/cli/commands/details/details.c +++ b/totp/cli/commands/details/details.c @@ -7,33 +7,59 @@ #include "../../../ui/scene_director.h" #include "../../cli_helpers.h" #include "../../common_command_arguments.h" +#include "formatters/table/details_output_formatter_table.h" +#include "formatters/tsv/details_output_formatter_tsv.h" -#define TOTP_CLI_PRINTF_AUTOMATION_FEATURE(description, header_printed) \ - do { \ - TOTP_CLI_PRINTF( \ - "| %-20s | %-28.28s |\r\n", \ - header_printed ? "" : "Automation features", \ - description); \ - header_printed = true; \ - } while(false) +typedef void (*TOTP_CLI_DETAILS_HEADER_FORMATTER)(); +typedef void (*TOTP_CLI_DETAILS_FOOTER_FORMATTER)(); +typedef void (*TOTP_CLI_DETAILS_AUTOMATION_FEATURE_ITEM_FORMATTER)(const char* key, const char* feature, bool* header_printed); +typedef void (*TOTP_CLI_DETAILS_CSTR_FORMATTER)(const char* key, const char* value); +typedef void (*TOTP_CLI_DETAILS_UINT8T_FORMATTER)(const char* key, uint8_t value); +typedef void (*TOTP_CLI_DETAILS_SIZET_FORMATTER)(const char* key, size_t value); -static void print_automation_features(const TokenInfo* token_info) { +typedef struct { + const TOTP_CLI_DETAILS_HEADER_FORMATTER header_formatter; + const TOTP_CLI_DETAILS_FOOTER_FORMATTER footer_formatter; + const TOTP_CLI_DETAILS_AUTOMATION_FEATURE_ITEM_FORMATTER automation_feature_item_formatter; + const TOTP_CLI_DETAILS_CSTR_FORMATTER cstr_formatter; + const TOTP_CLI_DETAILS_UINT8T_FORMATTER uint8t_formatter; + const TOTP_CLI_DETAILS_SIZET_FORMATTER sizet_formatter; +} TotpCliDetailsFormatter; + +static const TotpCliDetailsFormatter available_formatters[] = { + {.header_formatter = &details_output_formatter_print_header_table, + .footer_formatter = &details_output_formatter_print_footer_table, + .automation_feature_item_formatter = &details_output_formatter_print_automation_feature_table, + .cstr_formatter = &details_output_formatter_print_cstr_table, + .uint8t_formatter = &details_output_formatter_print_uint8t_table, + .sizet_formatter = &details_output_formatter_print_sizet_table}, + + {.header_formatter = &details_output_formatter_print_header_tsv, + .footer_formatter = &details_output_formatter_print_footer_tsv, + .automation_feature_item_formatter = &details_output_formatter_print_automation_feature_tsv, + .cstr_formatter = &details_output_formatter_print_cstr_tsv, + .uint8t_formatter = &details_output_formatter_print_uint8t_tsv, + .sizet_formatter = &details_output_formatter_print_sizet_tsv}, +}; + +static void print_automation_features(const TokenInfo* token_info, const TotpCliDetailsFormatter* formatter) { + bool header_printed = false; + const char* AUTOMATION_FEATURES_PRINT_KEY = "Automation features"; if(token_info->automation_features == TokenAutomationFeatureNone) { - TOTP_CLI_PRINTF("| %-20s | %-28.28s |\r\n", "Automation features", "None"); + (*formatter->automation_feature_item_formatter)(AUTOMATION_FEATURES_PRINT_KEY, "None", &header_printed); return; } - - bool header_printed = false; + if(token_info->automation_features & TokenAutomationFeatureEnterAtTheEnd) { - TOTP_CLI_PRINTF_AUTOMATION_FEATURE("Type key at the end", header_printed); + (*formatter->automation_feature_item_formatter)(AUTOMATION_FEATURES_PRINT_KEY, "Type key at the end", &header_printed); } if(token_info->automation_features & TokenAutomationFeatureTabAtTheEnd) { - TOTP_CLI_PRINTF_AUTOMATION_FEATURE("Type key at the end", header_printed); + (*formatter->automation_feature_item_formatter)(AUTOMATION_FEATURES_PRINT_KEY, "Type key at the end", &header_printed); } if(token_info->automation_features & TokenAutomationFeatureTypeSlower) { - TOTP_CLI_PRINTF_AUTOMATION_FEATURE("Type slower", header_printed); + (*formatter->automation_feature_item_formatter)(AUTOMATION_FEATURES_PRINT_KEY, "Type slower", &header_printed); } } @@ -64,6 +90,14 @@ void totp_cli_command_details_handle(PluginState* plugin_state, FuriString* args return; } + const TotpCliDetailsFormatter* formatter = &available_formatters[0]; + FuriString* arg = furi_string_alloc(); + if(args_read_string_and_trim(args, arg) && furi_string_cmpi_str(arg, "--tsv") == 0) { + formatter = &available_formatters[1]; + } + + furi_string_free(arg); + TOTP_CLI_LOCK_UI(plugin_state); size_t original_token_index = @@ -71,19 +105,14 @@ void totp_cli_command_details_handle(PluginState* plugin_state, FuriString* args if(totp_token_info_iterator_go_to(iterator_context, token_number - 1)) { const TokenInfo* token_info = totp_token_info_iterator_get_current_token(iterator_context); - TOTP_CLI_PRINTF("+----------------------+------------------------------+\r\n"); - TOTP_CLI_PRINTF("| %-20s | %-28s |\r\n", "Property", "Value"); - TOTP_CLI_PRINTF("+----------------------+------------------------------+\r\n"); - TOTP_CLI_PRINTF("| %-20s | %-28d |\r\n", "Index", token_number); - TOTP_CLI_PRINTF( - "| %-20s | %-28.28s |\r\n", "Name", furi_string_get_cstr(token_info->name)); - TOTP_CLI_PRINTF( - "| %-20s | %-28s |\r\n", "Hashing algorithm", token_info_get_algo_as_cstr(token_info)); - TOTP_CLI_PRINTF("| %-20s | %-28" PRIu8 " |\r\n", "Number of digits", token_info->digits); - TOTP_CLI_PRINTF( - "| %-20s | %" PRIu8 " sec.%-21s |\r\n", "Token lifetime", token_info->duration, " "); - print_automation_features(token_info); - TOTP_CLI_PRINTF("+----------------------+------------------------------+\r\n"); + (*formatter->header_formatter)(); + (*formatter->sizet_formatter)("Index", token_number); + (*formatter->cstr_formatter)("Name", furi_string_get_cstr(token_info->name)); + (*formatter->cstr_formatter)("Hashing algorithm", token_info_get_algo_as_cstr(token_info)); + (*formatter->uint8t_formatter)("Number of digits", token_info->digits); + (*formatter->uint8t_formatter)("Token lifetime", token_info->duration); + print_automation_features(token_info, formatter); + (*formatter->footer_formatter)(); } else { totp_cli_print_error_loading_token_info(); } diff --git a/totp/cli/commands/details/formatters/table/details_output_formatter_table.c b/totp/cli/commands/details/formatters/table/details_output_formatter_table.c new file mode 100644 index 00000000000..41245e8df82 --- /dev/null +++ b/totp/cli/commands/details/formatters/table/details_output_formatter_table.c @@ -0,0 +1,32 @@ +#include "details_output_formatter_table.h" +#include "../../../../cli_helpers.h" + +void details_output_formatter_print_header_table() { + TOTP_CLI_PRINTF("+----------------------+------------------------------+\r\n"); + TOTP_CLI_PRINTF("| %-20s | %-28s |\r\n", "Property", "Value"); + TOTP_CLI_PRINTF("+----------------------+------------------------------+\r\n"); +} + +void details_output_formatter_print_footer_table() { + TOTP_CLI_PRINTF("+----------------------+------------------------------+\r\n"); +} + +void details_output_formatter_print_automation_feature_table(const char* key, const char* feature, bool* header_printed) { + TOTP_CLI_PRINTF( + "| %-20s | %-28.28s |\r\n", + *header_printed ? "" : key, + feature); + *header_printed = true; +} + +void details_output_formatter_print_cstr_table(const char* key, const char* value) { + TOTP_CLI_PRINTF("| %-20s | %-28.28s |\r\n", key, value); +} + +void details_output_formatter_print_uint8t_table(const char* key, uint8_t value) { + TOTP_CLI_PRINTF("| %-20s | %-28" PRIu8 " |\r\n", key, value); +} + +void details_output_formatter_print_sizet_table(const char* key, size_t value) { + TOTP_CLI_PRINTF("| %-20s | %-28" PRIu16 " |\r\n", key, value); +} diff --git a/totp/cli/commands/details/formatters/table/details_output_formatter_table.h b/totp/cli/commands/details/formatters/table/details_output_formatter_table.h new file mode 100644 index 00000000000..ddbd77b8030 --- /dev/null +++ b/totp/cli/commands/details/formatters/table/details_output_formatter_table.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include +#include + +void details_output_formatter_print_header_table(); +void details_output_formatter_print_footer_table(); +void details_output_formatter_print_automation_feature_table(const char* key, const char* feature, bool* header_printed); +void details_output_formatter_print_cstr_table(const char* key, const char* value); +void details_output_formatter_print_uint8t_table(const char* key, uint8_t value); +void details_output_formatter_print_sizet_table(const char* key, size_t value); diff --git a/totp/cli/commands/details/formatters/tsv/details_output_formatter_tsv.c b/totp/cli/commands/details/formatters/tsv/details_output_formatter_tsv.c new file mode 100644 index 00000000000..0fe7fe4a414 --- /dev/null +++ b/totp/cli/commands/details/formatters/tsv/details_output_formatter_tsv.c @@ -0,0 +1,29 @@ +#include "details_output_formatter_tsv.h" +#include "../../../../cli_helpers.h" + +void details_output_formatter_print_header_tsv() { + TOTP_CLI_PRINTF("%s\t%s\r\n", "Property", "Value"); +} + +void details_output_formatter_print_footer_tsv() { +} + +void details_output_formatter_print_automation_feature_tsv(const char* key, const char* feature, bool* header_printed) { + TOTP_CLI_PRINTF( + "%s\t%s\r\n", + *header_printed ? "" : key, + feature); + *header_printed = true; +} + +void details_output_formatter_print_cstr_tsv(const char* key, const char* value) { + TOTP_CLI_PRINTF("%s\t%s\r\n", key, value); +} + +void details_output_formatter_print_uint8t_tsv(const char* key, uint8_t value) { + TOTP_CLI_PRINTF("%s\t%" PRIu8 "\r\n", key, value); +} + +void details_output_formatter_print_sizet_tsv(const char* key, size_t value) { + TOTP_CLI_PRINTF("%s\t%" PRIu16 "\r\n", key, value); +} diff --git a/totp/cli/commands/details/formatters/tsv/details_output_formatter_tsv.h b/totp/cli/commands/details/formatters/tsv/details_output_formatter_tsv.h new file mode 100644 index 00000000000..f7b0c7e3f36 --- /dev/null +++ b/totp/cli/commands/details/formatters/tsv/details_output_formatter_tsv.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include +#include + +void details_output_formatter_print_header_tsv(); +void details_output_formatter_print_footer_tsv(); +void details_output_formatter_print_automation_feature_tsv(const char* key, const char* feature, bool* header_printed); +void details_output_formatter_print_cstr_tsv(const char* key, const char* value); +void details_output_formatter_print_uint8t_tsv(const char* key, uint8_t value); +void details_output_formatter_print_sizet_tsv(const char* key, size_t value); diff --git a/totp/cli/commands/list/formatters/table/list_output_formatter_table.c b/totp/cli/commands/list/formatters/table/list_output_formatter_table.c new file mode 100644 index 00000000000..8774a6edc46 --- /dev/null +++ b/totp/cli/commands/list/formatters/table/list_output_formatter_table.c @@ -0,0 +1,22 @@ +#include "list_output_formatter_table.h" +#include "../../../../cli_helpers.h" + +void list_output_formatter_print_header_table() { + TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n"); + TOTP_CLI_PRINTF("| %-3s | %-25s | %-6s | %-s | %-s |\r\n", "#", "Name", "Algo", "Ln", "Dur"); + TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n"); +} + +void list_output_formatter_print_body_item_table(size_t index, const TokenInfo* token_info) { + TOTP_CLI_PRINTF( + "| %-3" PRIu16 " | %-25.25s | %-6s | %-2" PRIu8 " | %-3" PRIu8 " |\r\n", + index + 1, + furi_string_get_cstr(token_info->name), + token_info_get_algo_as_cstr(token_info), + token_info->digits, + token_info->duration); +} + +void list_output_formatter_print_footer_table() { + TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n"); +} \ No newline at end of file diff --git a/totp/cli/commands/list/formatters/table/list_output_formatter_table.h b/totp/cli/commands/list/formatters/table/list_output_formatter_table.h new file mode 100644 index 00000000000..e2ed9c4dcb7 --- /dev/null +++ b/totp/cli/commands/list/formatters/table/list_output_formatter_table.h @@ -0,0 +1,9 @@ +#pragma once + +#include "../../../../../types/token_info.h" + +void list_output_formatter_print_header_table(); + +void list_output_formatter_print_body_item_table(size_t index, const TokenInfo* token_info); + +void list_output_formatter_print_footer_table(); \ No newline at end of file diff --git a/totp/cli/commands/list/formatters/tsv/list_output_formatter_tsv.c b/totp/cli/commands/list/formatters/tsv/list_output_formatter_tsv.c new file mode 100644 index 00000000000..2bd4553973d --- /dev/null +++ b/totp/cli/commands/list/formatters/tsv/list_output_formatter_tsv.c @@ -0,0 +1,19 @@ +#include "list_output_formatter_tsv.h" +#include "../../../../cli_helpers.h" + +void list_output_formatter_print_header_tsv() { + TOTP_CLI_PRINTF("%s\t%s\t%s\t%s\t%s\r\n", "#", "Name", "Algo", "Ln", "Dur"); +} + +void list_output_formatter_print_body_item_tsv(size_t index, const TokenInfo* token_info) { + TOTP_CLI_PRINTF( + "%" PRIu16 "\t%s\t%s\t%" PRIu8 "\t%" PRIu8 "\r\n", + index + 1, + furi_string_get_cstr(token_info->name), + token_info_get_algo_as_cstr(token_info), + token_info->digits, + token_info->duration); +} + +void list_output_formatter_print_footer_tsv() { +} \ No newline at end of file diff --git a/totp/cli/commands/list/formatters/tsv/list_output_formatter_tsv.h b/totp/cli/commands/list/formatters/tsv/list_output_formatter_tsv.h new file mode 100644 index 00000000000..e01c95d2e37 --- /dev/null +++ b/totp/cli/commands/list/formatters/tsv/list_output_formatter_tsv.h @@ -0,0 +1,9 @@ +#pragma once + +#include "../../../../../types/token_info.h" + +void list_output_formatter_print_header_tsv(); + +void list_output_formatter_print_body_item_tsv(size_t index, const TokenInfo* token_info); + +void list_output_formatter_print_footer_tsv(); \ No newline at end of file diff --git a/totp/cli/commands/list/list.c b/totp/cli/commands/list/list.c index d5c97c6b06d..4822bd61bc8 100644 --- a/totp/cli/commands/list/list.c +++ b/totp/cli/commands/list/list.c @@ -1,10 +1,33 @@ #include "list.h" #include +#include #include "../../../types/token_info.h" #include "../../../services/config/constants.h" #include "../../../services/config/config.h" #include "../../../ui/scene_director.h" #include "../../cli_helpers.h" +#include "formatters/table/list_output_formatter_table.h" +#include "formatters/tsv/list_output_formatter_tsv.h" + +typedef void (*TOTP_CLI_LIST_HEADER_FORMATTER)(); +typedef void (*TOTP_CLI_LIST_FOOTER_FORMATTER)(); +typedef void (*TOTP_CLI_LIST_BODY_ITEM_FORMATTER)(size_t index, const TokenInfo* token_info); + +typedef struct { + const TOTP_CLI_LIST_HEADER_FORMATTER header_formatter; + const TOTP_CLI_LIST_FOOTER_FORMATTER footer_formatter; + const TOTP_CLI_LIST_BODY_ITEM_FORMATTER body_item_formatter; +} TotpCliListFormatter; + +static const TotpCliListFormatter available_formatters[] = { + {.header_formatter = &list_output_formatter_print_header_table, + .body_item_formatter = &list_output_formatter_print_body_item_table, + .footer_formatter = &list_output_formatter_print_footer_table}, + + {.header_formatter = &list_output_formatter_print_header_tsv, + .body_item_formatter = &list_output_formatter_print_body_item_tsv, + .footer_formatter = &list_output_formatter_print_footer_tsv} +}; #ifdef TOTP_CLI_RICH_HELP_ENABLED void totp_cli_command_list_docopt_commands() { @@ -18,7 +41,7 @@ void totp_cli_command_list_docopt_usage() { } #endif -void totp_cli_command_list_handle(PluginState* plugin_state, Cli* cli) { +void totp_cli_command_list_handle(PluginState* plugin_state, FuriString* args, Cli* cli) { if(!totp_cli_ensure_authenticated(plugin_state, cli)) { return; } @@ -31,26 +54,26 @@ void totp_cli_command_list_handle(PluginState* plugin_state, Cli* cli) { return; } + const TotpCliListFormatter* formatter = &available_formatters[0]; + FuriString* arg = furi_string_alloc(); + if(args_read_string_and_trim(args, arg) && furi_string_cmpi_str(arg, "--tsv") == 0) { + formatter = &available_formatters[1]; + } + + furi_string_free(arg); + TOTP_CLI_LOCK_UI(plugin_state); size_t original_index = totp_token_info_iterator_get_current_token_index(iterator_context); - TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n"); - TOTP_CLI_PRINTF("| %-3s | %-25s | %-6s | %-s | %-s |\r\n", "#", "Name", "Algo", "Ln", "Dur"); - TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n"); + (*formatter->header_formatter)(); for(size_t i = 0; i < total_count; i++) { totp_token_info_iterator_go_to(iterator_context, i); const TokenInfo* token_info = totp_token_info_iterator_get_current_token(iterator_context); - TOTP_CLI_PRINTF( - "| %-3" PRIu16 " | %-25.25s | %-6s | %-2" PRIu8 " | %-3" PRIu8 " |\r\n", - i + 1, - furi_string_get_cstr(token_info->name), - token_info_get_algo_as_cstr(token_info), - token_info->digits, - token_info->duration); + (*formatter->body_item_formatter)(i, token_info); } - TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n"); + (*formatter->footer_formatter)(); totp_token_info_iterator_go_to(iterator_context, original_index); diff --git a/totp/cli/commands/list/list.h b/totp/cli/commands/list/list.h index 8237bfd2bdd..0527e8c5f36 100644 --- a/totp/cli/commands/list/list.h +++ b/totp/cli/commands/list/list.h @@ -7,7 +7,7 @@ #define TOTP_CLI_COMMAND_LIST "list" #define TOTP_CLI_COMMAND_LIST_ALT "ls" -void totp_cli_command_list_handle(PluginState* plugin_state, Cli* cli); +void totp_cli_command_list_handle(PluginState* plugin_state, FuriString* args, Cli* cli); #ifdef TOTP_CLI_RICH_HELP_ENABLED void totp_cli_command_list_docopt_commands(); void totp_cli_command_list_docopt_usage();