Skip to content

Commit 8bc969d

Browse files
committed
Implemented #193
1 parent 87363b8 commit 8bc969d

12 files changed

+238
-42
lines changed

totp/cli/cli.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ static void totp_cli_handler(Cli* cli, FuriString* args, void* context) {
4747
} else if(
4848
furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_LIST) == 0 ||
4949
furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_LIST_ALT) == 0) {
50-
totp_cli_command_list_handle(plugin_state, cli);
50+
totp_cli_command_list_handle(plugin_state, args, cli);
5151
} else if(
5252
furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_DELETE) == 0 ||
5353
furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_DELETE_ALT) == 0) {

totp/cli/commands/details/details.c

+57-28
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,59 @@
77
#include "../../../ui/scene_director.h"
88
#include "../../cli_helpers.h"
99
#include "../../common_command_arguments.h"
10+
#include "formatters/table/details_output_formatter_table.h"
11+
#include "formatters/tsv/details_output_formatter_tsv.h"
1012

11-
#define TOTP_CLI_PRINTF_AUTOMATION_FEATURE(description, header_printed) \
12-
do { \
13-
TOTP_CLI_PRINTF( \
14-
"| %-20s | %-28.28s |\r\n", \
15-
header_printed ? "" : "Automation features", \
16-
description); \
17-
header_printed = true; \
18-
} while(false)
13+
typedef void (*TOTP_CLI_DETAILS_HEADER_FORMATTER)();
14+
typedef void (*TOTP_CLI_DETAILS_FOOTER_FORMATTER)();
15+
typedef void (*TOTP_CLI_DETAILS_AUTOMATION_FEATURE_ITEM_FORMATTER)(const char* key, const char* feature, bool* header_printed);
16+
typedef void (*TOTP_CLI_DETAILS_CSTR_FORMATTER)(const char* key, const char* value);
17+
typedef void (*TOTP_CLI_DETAILS_UINT8T_FORMATTER)(const char* key, uint8_t value);
18+
typedef void (*TOTP_CLI_DETAILS_SIZET_FORMATTER)(const char* key, size_t value);
1919

20-
static void print_automation_features(const TokenInfo* token_info) {
20+
typedef struct {
21+
const TOTP_CLI_DETAILS_HEADER_FORMATTER header_formatter;
22+
const TOTP_CLI_DETAILS_FOOTER_FORMATTER footer_formatter;
23+
const TOTP_CLI_DETAILS_AUTOMATION_FEATURE_ITEM_FORMATTER automation_feature_item_formatter;
24+
const TOTP_CLI_DETAILS_CSTR_FORMATTER cstr_formatter;
25+
const TOTP_CLI_DETAILS_UINT8T_FORMATTER uint8t_formatter;
26+
const TOTP_CLI_DETAILS_SIZET_FORMATTER sizet_formatter;
27+
} TotpCliDetailsFormatter;
28+
29+
static const TotpCliDetailsFormatter available_formatters[] = {
30+
{.header_formatter = &details_output_formatter_print_header_table,
31+
.footer_formatter = &details_output_formatter_print_footer_table,
32+
.automation_feature_item_formatter = &details_output_formatter_print_automation_feature_table,
33+
.cstr_formatter = &details_output_formatter_print_cstr_table,
34+
.uint8t_formatter = &details_output_formatter_print_uint8t_table,
35+
.sizet_formatter = &details_output_formatter_print_sizet_table},
36+
37+
{.header_formatter = &details_output_formatter_print_header_tsv,
38+
.footer_formatter = &details_output_formatter_print_footer_tsv,
39+
.automation_feature_item_formatter = &details_output_formatter_print_automation_feature_tsv,
40+
.cstr_formatter = &details_output_formatter_print_cstr_tsv,
41+
.uint8t_formatter = &details_output_formatter_print_uint8t_tsv,
42+
.sizet_formatter = &details_output_formatter_print_sizet_tsv},
43+
};
44+
45+
static void print_automation_features(const TokenInfo* token_info, const TotpCliDetailsFormatter* formatter) {
46+
bool header_printed = false;
47+
const char* AUTOMATION_FEATURES_PRINT_KEY = "Automation features";
2148
if(token_info->automation_features == TokenAutomationFeatureNone) {
22-
TOTP_CLI_PRINTF("| %-20s | %-28.28s |\r\n", "Automation features", "None");
49+
(*formatter->automation_feature_item_formatter)(AUTOMATION_FEATURES_PRINT_KEY, "None", &header_printed);
2350
return;
2451
}
25-
26-
bool header_printed = false;
52+
2753
if(token_info->automation_features & TokenAutomationFeatureEnterAtTheEnd) {
28-
TOTP_CLI_PRINTF_AUTOMATION_FEATURE("Type <Enter> key at the end", header_printed);
54+
(*formatter->automation_feature_item_formatter)(AUTOMATION_FEATURES_PRINT_KEY, "Type <Enter> key at the end", &header_printed);
2955
}
3056

3157
if(token_info->automation_features & TokenAutomationFeatureTabAtTheEnd) {
32-
TOTP_CLI_PRINTF_AUTOMATION_FEATURE("Type <Tab> key at the end", header_printed);
58+
(*formatter->automation_feature_item_formatter)(AUTOMATION_FEATURES_PRINT_KEY, "Type <Tab> key at the end", &header_printed);
3359
}
3460

3561
if(token_info->automation_features & TokenAutomationFeatureTypeSlower) {
36-
TOTP_CLI_PRINTF_AUTOMATION_FEATURE("Type slower", header_printed);
62+
(*formatter->automation_feature_item_formatter)(AUTOMATION_FEATURES_PRINT_KEY, "Type slower", &header_printed);
3763
}
3864
}
3965

@@ -64,26 +90,29 @@ void totp_cli_command_details_handle(PluginState* plugin_state, FuriString* args
6490
return;
6591
}
6692

93+
const TotpCliDetailsFormatter* formatter = &available_formatters[0];
94+
FuriString* arg = furi_string_alloc();
95+
if(args_read_string_and_trim(args, arg) && furi_string_cmpi_str(arg, "--tsv") == 0) {
96+
formatter = &available_formatters[1];
97+
}
98+
99+
furi_string_free(arg);
100+
67101
TOTP_CLI_LOCK_UI(plugin_state);
68102

69103
size_t original_token_index =
70104
totp_token_info_iterator_get_current_token_index(iterator_context);
71105
if(totp_token_info_iterator_go_to(iterator_context, token_number - 1)) {
72106
const TokenInfo* token_info = totp_token_info_iterator_get_current_token(iterator_context);
73107

74-
TOTP_CLI_PRINTF("+----------------------+------------------------------+\r\n");
75-
TOTP_CLI_PRINTF("| %-20s | %-28s |\r\n", "Property", "Value");
76-
TOTP_CLI_PRINTF("+----------------------+------------------------------+\r\n");
77-
TOTP_CLI_PRINTF("| %-20s | %-28d |\r\n", "Index", token_number);
78-
TOTP_CLI_PRINTF(
79-
"| %-20s | %-28.28s |\r\n", "Name", furi_string_get_cstr(token_info->name));
80-
TOTP_CLI_PRINTF(
81-
"| %-20s | %-28s |\r\n", "Hashing algorithm", token_info_get_algo_as_cstr(token_info));
82-
TOTP_CLI_PRINTF("| %-20s | %-28" PRIu8 " |\r\n", "Number of digits", token_info->digits);
83-
TOTP_CLI_PRINTF(
84-
"| %-20s | %" PRIu8 " sec.%-21s |\r\n", "Token lifetime", token_info->duration, " ");
85-
print_automation_features(token_info);
86-
TOTP_CLI_PRINTF("+----------------------+------------------------------+\r\n");
108+
(*formatter->header_formatter)();
109+
(*formatter->sizet_formatter)("Index", token_number);
110+
(*formatter->cstr_formatter)("Name", furi_string_get_cstr(token_info->name));
111+
(*formatter->cstr_formatter)("Hashing algorithm", token_info_get_algo_as_cstr(token_info));
112+
(*formatter->uint8t_formatter)("Number of digits", token_info->digits);
113+
(*formatter->uint8t_formatter)("Token lifetime", token_info->duration);
114+
print_automation_features(token_info, formatter);
115+
(*formatter->footer_formatter)();
87116
} else {
88117
totp_cli_print_error_loading_token_info();
89118
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include "details_output_formatter_table.h"
2+
#include "../../../../cli_helpers.h"
3+
4+
void details_output_formatter_print_header_table() {
5+
TOTP_CLI_PRINTF("+----------------------+------------------------------+\r\n");
6+
TOTP_CLI_PRINTF("| %-20s | %-28s |\r\n", "Property", "Value");
7+
TOTP_CLI_PRINTF("+----------------------+------------------------------+\r\n");
8+
}
9+
10+
void details_output_formatter_print_footer_table() {
11+
TOTP_CLI_PRINTF("+----------------------+------------------------------+\r\n");
12+
}
13+
14+
void details_output_formatter_print_automation_feature_table(const char* key, const char* feature, bool* header_printed) {
15+
TOTP_CLI_PRINTF(
16+
"| %-20s | %-28.28s |\r\n",
17+
*header_printed ? "" : key,
18+
feature);
19+
*header_printed = true;
20+
}
21+
22+
void details_output_formatter_print_cstr_table(const char* key, const char* value) {
23+
TOTP_CLI_PRINTF("| %-20s | %-28.28s |\r\n", key, value);
24+
}
25+
26+
void details_output_formatter_print_uint8t_table(const char* key, uint8_t value) {
27+
TOTP_CLI_PRINTF("| %-20s | %-28" PRIu8 " |\r\n", key, value);
28+
}
29+
30+
void details_output_formatter_print_sizet_table(const char* key, size_t value) {
31+
TOTP_CLI_PRINTF("| %-20s | %-28" PRIu16 " |\r\n", key, value);
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#pragma once
2+
3+
#include <stdint.h>
4+
#include <stddef.h>
5+
#include <stdbool.h>
6+
7+
void details_output_formatter_print_header_table();
8+
void details_output_formatter_print_footer_table();
9+
void details_output_formatter_print_automation_feature_table(const char* key, const char* feature, bool* header_printed);
10+
void details_output_formatter_print_cstr_table(const char* key, const char* value);
11+
void details_output_formatter_print_uint8t_table(const char* key, uint8_t value);
12+
void details_output_formatter_print_sizet_table(const char* key, size_t value);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include "details_output_formatter_tsv.h"
2+
#include "../../../../cli_helpers.h"
3+
4+
void details_output_formatter_print_header_tsv() {
5+
TOTP_CLI_PRINTF("%s\t%s\r\n", "Property", "Value");
6+
}
7+
8+
void details_output_formatter_print_footer_tsv() {
9+
}
10+
11+
void details_output_formatter_print_automation_feature_tsv(const char* key, const char* feature, bool* header_printed) {
12+
TOTP_CLI_PRINTF(
13+
"%s\t%s\r\n",
14+
*header_printed ? "" : key,
15+
feature);
16+
*header_printed = true;
17+
}
18+
19+
void details_output_formatter_print_cstr_tsv(const char* key, const char* value) {
20+
TOTP_CLI_PRINTF("%s\t%s\r\n", key, value);
21+
}
22+
23+
void details_output_formatter_print_uint8t_tsv(const char* key, uint8_t value) {
24+
TOTP_CLI_PRINTF("%s\t%" PRIu8 "\r\n", key, value);
25+
}
26+
27+
void details_output_formatter_print_sizet_tsv(const char* key, size_t value) {
28+
TOTP_CLI_PRINTF("%s\t%" PRIu16 "\r\n", key, value);
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#pragma once
2+
3+
#include <stdint.h>
4+
#include <stddef.h>
5+
#include <stdbool.h>
6+
7+
void details_output_formatter_print_header_tsv();
8+
void details_output_formatter_print_footer_tsv();
9+
void details_output_formatter_print_automation_feature_tsv(const char* key, const char* feature, bool* header_printed);
10+
void details_output_formatter_print_cstr_tsv(const char* key, const char* value);
11+
void details_output_formatter_print_uint8t_tsv(const char* key, uint8_t value);
12+
void details_output_formatter_print_sizet_tsv(const char* key, size_t value);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include "list_output_formatter_table.h"
2+
#include "../../../../cli_helpers.h"
3+
4+
void list_output_formatter_print_header_table() {
5+
TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n");
6+
TOTP_CLI_PRINTF("| %-3s | %-25s | %-6s | %-s | %-s |\r\n", "#", "Name", "Algo", "Ln", "Dur");
7+
TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n");
8+
}
9+
10+
void list_output_formatter_print_body_item_table(size_t index, const TokenInfo* token_info) {
11+
TOTP_CLI_PRINTF(
12+
"| %-3" PRIu16 " | %-25.25s | %-6s | %-2" PRIu8 " | %-3" PRIu8 " |\r\n",
13+
index + 1,
14+
furi_string_get_cstr(token_info->name),
15+
token_info_get_algo_as_cstr(token_info),
16+
token_info->digits,
17+
token_info->duration);
18+
}
19+
20+
void list_output_formatter_print_footer_table() {
21+
TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n");
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
#include "../../../../../types/token_info.h"
4+
5+
void list_output_formatter_print_header_table();
6+
7+
void list_output_formatter_print_body_item_table(size_t index, const TokenInfo* token_info);
8+
9+
void list_output_formatter_print_footer_table();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include "list_output_formatter_tsv.h"
2+
#include "../../../../cli_helpers.h"
3+
4+
void list_output_formatter_print_header_tsv() {
5+
TOTP_CLI_PRINTF("%s\t%s\t%s\t%s\t%s\r\n", "#", "Name", "Algo", "Ln", "Dur");
6+
}
7+
8+
void list_output_formatter_print_body_item_tsv(size_t index, const TokenInfo* token_info) {
9+
TOTP_CLI_PRINTF(
10+
"%" PRIu16 "\t%s\t%s\t%" PRIu8 "\t%" PRIu8 "\r\n",
11+
index + 1,
12+
furi_string_get_cstr(token_info->name),
13+
token_info_get_algo_as_cstr(token_info),
14+
token_info->digits,
15+
token_info->duration);
16+
}
17+
18+
void list_output_formatter_print_footer_tsv() {
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
#include "../../../../../types/token_info.h"
4+
5+
void list_output_formatter_print_header_tsv();
6+
7+
void list_output_formatter_print_body_item_tsv(size_t index, const TokenInfo* token_info);
8+
9+
void list_output_formatter_print_footer_tsv();

totp/cli/commands/list/list.c

+35-12
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,33 @@
11
#include "list.h"
22
#include <stdlib.h>
3+
#include <lib/toolbox/args.h>
34
#include "../../../types/token_info.h"
45
#include "../../../services/config/constants.h"
56
#include "../../../services/config/config.h"
67
#include "../../../ui/scene_director.h"
78
#include "../../cli_helpers.h"
9+
#include "formatters/table/list_output_formatter_table.h"
10+
#include "formatters/tsv/list_output_formatter_tsv.h"
11+
12+
typedef void (*TOTP_CLI_LIST_HEADER_FORMATTER)();
13+
typedef void (*TOTP_CLI_LIST_FOOTER_FORMATTER)();
14+
typedef void (*TOTP_CLI_LIST_BODY_ITEM_FORMATTER)(size_t index, const TokenInfo* token_info);
15+
16+
typedef struct {
17+
const TOTP_CLI_LIST_HEADER_FORMATTER header_formatter;
18+
const TOTP_CLI_LIST_FOOTER_FORMATTER footer_formatter;
19+
const TOTP_CLI_LIST_BODY_ITEM_FORMATTER body_item_formatter;
20+
} TotpCliListFormatter;
21+
22+
static const TotpCliListFormatter available_formatters[] = {
23+
{.header_formatter = &list_output_formatter_print_header_table,
24+
.body_item_formatter = &list_output_formatter_print_body_item_table,
25+
.footer_formatter = &list_output_formatter_print_footer_table},
26+
27+
{.header_formatter = &list_output_formatter_print_header_tsv,
28+
.body_item_formatter = &list_output_formatter_print_body_item_tsv,
29+
.footer_formatter = &list_output_formatter_print_footer_tsv}
30+
};
831

932
#ifdef TOTP_CLI_RICH_HELP_ENABLED
1033
void totp_cli_command_list_docopt_commands() {
@@ -18,7 +41,7 @@ void totp_cli_command_list_docopt_usage() {
1841
}
1942
#endif
2043

21-
void totp_cli_command_list_handle(PluginState* plugin_state, Cli* cli) {
44+
void totp_cli_command_list_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
2245
if(!totp_cli_ensure_authenticated(plugin_state, cli)) {
2346
return;
2447
}
@@ -31,26 +54,26 @@ void totp_cli_command_list_handle(PluginState* plugin_state, Cli* cli) {
3154
return;
3255
}
3356

57+
const TotpCliListFormatter* formatter = &available_formatters[0];
58+
FuriString* arg = furi_string_alloc();
59+
if(args_read_string_and_trim(args, arg) && furi_string_cmpi_str(arg, "--tsv") == 0) {
60+
formatter = &available_formatters[1];
61+
}
62+
63+
furi_string_free(arg);
64+
3465
TOTP_CLI_LOCK_UI(plugin_state);
3566

3667
size_t original_index = totp_token_info_iterator_get_current_token_index(iterator_context);
3768

38-
TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n");
39-
TOTP_CLI_PRINTF("| %-3s | %-25s | %-6s | %-s | %-s |\r\n", "#", "Name", "Algo", "Ln", "Dur");
40-
TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n");
69+
(*formatter->header_formatter)();
4170
for(size_t i = 0; i < total_count; i++) {
4271
totp_token_info_iterator_go_to(iterator_context, i);
4372
const TokenInfo* token_info = totp_token_info_iterator_get_current_token(iterator_context);
44-
TOTP_CLI_PRINTF(
45-
"| %-3" PRIu16 " | %-25.25s | %-6s | %-2" PRIu8 " | %-3" PRIu8 " |\r\n",
46-
i + 1,
47-
furi_string_get_cstr(token_info->name),
48-
token_info_get_algo_as_cstr(token_info),
49-
token_info->digits,
50-
token_info->duration);
73+
(*formatter->body_item_formatter)(i, token_info);
5174
}
5275

53-
TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n");
76+
(*formatter->footer_formatter)();
5477

5578
totp_token_info_iterator_go_to(iterator_context, original_index);
5679

totp/cli/commands/list/list.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#define TOTP_CLI_COMMAND_LIST "list"
88
#define TOTP_CLI_COMMAND_LIST_ALT "ls"
99

10-
void totp_cli_command_list_handle(PluginState* plugin_state, Cli* cli);
10+
void totp_cli_command_list_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
1111
#ifdef TOTP_CLI_RICH_HELP_ENABLED
1212
void totp_cli_command_list_docopt_commands();
1313
void totp_cli_command_list_docopt_usage();

0 commit comments

Comments
 (0)