ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
options/strings.c
Go to the documentation of this file.
1
14#include <ascii-chat/options/options.h> // For asciichat_mode_t and MODE_ enums
15#include <ascii-chat/options/strings.h>
16#include <ascii-chat/options/levenshtein.h>
17#include <ascii-chat/options/enums.h>
18#include <ascii-chat/platform/terminal.h> // For term_color_level_t
19#include <ascii-chat/video/palette.h> // For palette_type_t
20#include <ascii-chat/common.h>
21#include <string.h>
22#include <stdio.h>
23
24// ============================================================================
25// Mode String Conversions
26// ============================================================================
27
31typedef struct {
32 asciichat_mode_t mode;
33 const char *name;
34 const char *description;
36
44static const mode_descriptor_t mode_registry[] = {
45 {MODE_SERVER, "server", "Multi-client video chat server"},
46 {MODE_CLIENT, "client", "Connect to ascii-chat server"},
47 {MODE_MIRROR, "mirror", "Local webcam preview (no networking)"},
48 {MODE_DISCOVERY_SERVICE, "discovery-service", "Session discovery server (ACDS)"},
49 {MODE_DISCOVERY_SERVICE, "acds", "Alias for discovery-service"},
50 {MODE_INVALID, NULL, NULL} // Terminator
51};
52
53const char *asciichat_mode_to_string(asciichat_mode_t mode) {
54 // Special case: MODE_DISCOVERY is the default mode, show as "default" to users
55 if (mode == MODE_DISCOVERY) {
56 return "default";
57 }
58
59 for (size_t i = 0; mode_registry[i].name != NULL; i++) {
60 if (mode_registry[i].mode == mode) {
61 return mode_registry[i].name;
62 }
63 }
64 return "unknown";
65}
66
67asciichat_mode_t asciichat_string_to_mode(const char *str) {
68 if (!str) {
69 return MODE_INVALID;
70 }
71
72 for (size_t i = 0; mode_registry[i].name != NULL; i++) {
73 if (strcmp(mode_registry[i].name, str) == 0) {
74 return mode_registry[i].mode;
75 }
76 }
77
78 return MODE_INVALID;
79}
80
81bool asciichat_is_valid_mode_string(const char *str) {
82 return asciichat_string_to_mode(str) != MODE_INVALID;
83}
84
85size_t asciichat_get_all_mode_strings(const char ***out_names) {
86 static const char *names[32]; // Max 32 modes
87 size_t count = 0;
88
89 for (size_t i = 0; mode_registry[i].name != NULL && count < 32; i++) {
90 // Skip duplicates (like "acds" alias)
91 bool duplicate = false;
92 for (size_t j = 0; j < count; j++) {
93 if (strcmp(names[j], mode_registry[i].name) == 0) {
94 duplicate = true;
95 break;
96 }
97 }
98 if (!duplicate) {
99 names[count++] = mode_registry[i].name;
100 }
101 }
102
103 if (out_names) {
104 *out_names = names;
105 }
106 return count;
107}
108
109const char *asciichat_suggest_mode(const char *input) {
110 if (!input) {
111 return NULL;
112 }
113
114 const char **names = NULL;
115 size_t count = asciichat_get_all_mode_strings(&names);
116
117 // Create NULL-terminated array for levenshtein_find_similar
118 static const char *null_terminated[33]; // Max 32 modes + NULL
119 for (size_t i = 0; i < count && i < 32; i++) {
120 null_terminated[i] = names[i];
121 }
122 null_terminated[count] = NULL;
123
124 return levenshtein_find_similar(input, null_terminated);
125}
126
127// ============================================================================
128// Color Mode String Conversions
129// ============================================================================
130
131const char *color_mode_to_string(terminal_color_mode_t mode) {
132 switch (mode) {
133 case TERM_COLOR_AUTO:
134 return "auto";
135 case TERM_COLOR_NONE:
136 return "none";
137 case TERM_COLOR_16:
138 return "16";
139 case TERM_COLOR_256:
140 return "256";
141 case TERM_COLOR_TRUECOLOR:
142 return "truecolor";
143 default:
144 return "unknown";
145 }
146}
147
148// ============================================================================
149// Render Mode String Conversions
150// ============================================================================
151
152const char *render_mode_to_string(render_mode_t mode) {
153 switch (mode) {
154 case RENDER_MODE_FOREGROUND:
155 return "foreground";
156 case RENDER_MODE_BACKGROUND:
157 return "background";
158 case RENDER_MODE_HALF_BLOCK:
159 return "half-block";
160 default:
161 return "unknown";
162 }
163}
164
165// ============================================================================
166// Palette Type String Conversions
167// ============================================================================
168
169const char *palette_type_to_string(palette_type_t type) {
170 switch (type) {
171 case PALETTE_STANDARD:
172 return "standard";
173 case PALETTE_BLOCKS:
174 return "blocks";
175 case PALETTE_DIGITAL:
176 return "digital";
177 case PALETTE_MINIMAL:
178 return "minimal";
179 case PALETTE_COOL:
180 return "cool";
181 case PALETTE_CUSTOM:
182 return "custom";
183 default:
184 return "unknown";
185 }
186}
187
188// ============================================================================
189// Generic Enum Value Fuzzy Matching
190// ============================================================================
191
192const char *asciichat_suggest_enum_value(const char *option_name, const char *input) {
193 if (!option_name || !input) {
194 return NULL;
195 }
196
197 size_t value_count = 0;
198 const char **values = options_get_enum_values(option_name, &value_count);
199
200 if (!values || value_count == 0) {
201 return NULL;
202 }
203
204 // Create NULL-terminated array for levenshtein_find_similar
205 static const char *null_terminated[64]; // Max 64 enum values
206 for (size_t i = 0; i < value_count && i < 63; i++) {
207 null_terminated[i] = values[i];
208 }
209 null_terminated[value_count] = NULL;
210
211 return levenshtein_find_similar(input, null_terminated);
212}
const char ** options_get_enum_values(const char *option_name, size_t *value_count)
Definition enums.c:49
const char * levenshtein_find_similar(const char *unknown, const char *const *candidates)
const char * color_mode_to_string(terminal_color_mode_t mode)
asciichat_mode_t asciichat_string_to_mode(const char *str)
const char * render_mode_to_string(render_mode_t mode)
const char * asciichat_mode_to_string(asciichat_mode_t mode)
const char * asciichat_suggest_mode(const char *input)
bool asciichat_is_valid_mode_string(const char *str)
size_t asciichat_get_all_mode_strings(const char ***out_names)
const char * palette_type_to_string(palette_type_t type)
const char * asciichat_suggest_enum_value(const char *option_name, const char *input)
Mode descriptor for string conversion.
const char * description
asciichat_mode_t mode