Skip to content

Commit 9f670f9

Browse files
Perdixkycodex
andcommitted
style: format cli reader
Apply clang-format to include/rfl/cli/Reader.hpp only. Signed-off-by: Perdixky <3293789706@qq.com> Co-authored-by: Codex <codex@openai.com>
1 parent 2553f20 commit 9f670f9

1 file changed

Lines changed: 71 additions & 80 deletions

File tree

include/rfl/cli/Reader.hpp

Lines changed: 71 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
#define RFL_CLI_READER_HPP_
33

44
#include <charconv>
5-
#include <concepts>
65
#include <clocale>
6+
#include <concepts>
77
#include <cstdlib>
88
#include <map>
99
#include <optional>
@@ -26,9 +26,10 @@ inline constexpr char path_separator = '.';
2626
/// Example: `--ports=8080,8081,8082` for an array of ports.
2727
inline constexpr char array_delimiter = ',';
2828

29-
/// Represents a CLI variable that can be a direct value or a path in the argument map.
30-
/// The `path` represents the hierarchical key (e.g., "database.host").
31-
/// The `direct_value` is used when parsing array elements directly.
29+
/// Represents a CLI variable that can be a direct value or a path in the
30+
/// argument map. The `path` represents the hierarchical key (e.g.,
31+
/// "database.host"). The `direct_value` is used when parsing array elements
32+
/// directly.
3233
struct CliVarType {
3334
const std::map<std::string, std::string>* const args = nullptr;
3435
const std::string path;
@@ -55,10 +56,10 @@ struct CliArrayType {
5556
/// @param _str The string to parse
5657
/// @param _path The CLI argument path (unused for strings)
5758
/// @return The string unchanged
58-
template <class T> requires std::same_as<T, std::string>
59-
rfl::Result<T> parse_value(
60-
const std::string& _str, const std::string&
61-
) noexcept {
59+
template <class T>
60+
requires std::same_as<T, std::string>
61+
rfl::Result<T> parse_value(const std::string& _str,
62+
const std::string&) noexcept {
6263
return _str;
6364
}
6465

@@ -68,22 +69,23 @@ rfl::Result<T> parse_value(
6869
/// @param _str The string to parse
6970
/// @param _path The CLI argument path (for error messages)
7071
/// @return A Result containing the boolean value or an error
71-
template <class T> requires std::same_as<T, bool>
72-
rfl::Result<T> parse_value(
73-
const std::string& _str, const std::string& _path
74-
) noexcept {
72+
template <class T>
73+
requires std::same_as<T, bool>
74+
rfl::Result<T> parse_value(const std::string& _str,
75+
const std::string& _path) noexcept {
7576
if (_str.empty() || _str == "true" || _str == "1") {
7677
return true;
7778
}
7879
if (_str == "false" || _str == "0") {
7980
return false;
8081
}
81-
return error(
82-
"Could not cast '" + _str + "' to boolean for key '" + _path + "'.");
82+
return error("Could not cast '" + _str + "' to boolean for key '" + _path +
83+
"'.");
8384
}
8485

8586
/// Parses a string value to a floating-point number.
86-
/// Uses locale-independent parsing (C locale) to ensure "3.14" works consistently.
87+
/// Uses locale-independent parsing (C locale) to ensure "3.14" works
88+
/// consistently.
8789
/// @tparam T Must be a floating-point type (float, double, long double)
8890
/// @param _str The string to parse
8991
/// @param _path The CLI argument path (for error messages)
@@ -92,10 +94,10 @@ rfl::Result<T> parse_value(
9294
// std::strtod depends on the C locale (LC_NUMERIC), so "3.14" can fail
9395
// under locales that use comma as decimal separator.
9496
// Use strtod_l with an explicit "C" locale on all platforms for consistency.
95-
template <class T> requires (std::is_floating_point_v<T>)
96-
rfl::Result<T> parse_value(
97-
const std::string& _str, const std::string& _path
98-
) noexcept {
97+
template <class T>
98+
requires(std::is_floating_point_v<T>)
99+
rfl::Result<T> parse_value(const std::string& _str,
100+
const std::string& _path) noexcept {
99101
char* end = nullptr;
100102
#ifdef _WIN32
101103
const auto c_locale = _create_locale(LC_NUMERIC, "C");
@@ -107,8 +109,8 @@ rfl::Result<T> parse_value(
107109
freelocale(c_locale);
108110
#endif
109111
if (end != _str.c_str() + _str.size()) {
110-
return error(
111-
"Could not cast '" + _str + "' to floating point for key '" + _path + "'.");
112+
return error("Could not cast '" + _str + "' to floating point for key '" +
113+
_path + "'.");
112114
}
113115
return static_cast<T>(value);
114116
}
@@ -119,23 +121,24 @@ rfl::Result<T> parse_value(
119121
/// @param _str The string to parse
120122
/// @param _path The CLI argument path (for error messages)
121123
/// @return A Result containing the parsed integer or an error
122-
template <class T> requires (std::is_integral_v<T> && !std::same_as<T, bool>)
123-
rfl::Result<T> parse_value(
124-
const std::string& _str, const std::string& _path
125-
) noexcept {
124+
template <class T>
125+
requires(std::is_integral_v<T> && !std::same_as<T, bool>)
126+
rfl::Result<T> parse_value(const std::string& _str,
127+
const std::string& _path) noexcept {
126128
T value;
127129
const auto [ptr, ec] =
128130
std::from_chars(_str.data(), _str.data() + _str.size(), value);
129131
if (ec != std::errc() || ptr != _str.data() + _str.size()) {
130-
return error(
131-
"Could not cast '" + _str + "' to integer for key '" + _path + "'.");
132+
return error("Could not cast '" + _str + "' to integer for key '" + _path +
133+
"'.");
132134
}
133135
return value;
134136
}
135137

136138
/// Reader for command-line interface arguments.
137-
/// Parses hierarchical key-value pairs from CLI arguments (e.g., --database.host=localhost).
138-
/// Supports arrays through comma-delimited values (e.g., --ports=8080,8081).
139+
/// Parses hierarchical key-value pairs from CLI arguments (e.g.,
140+
/// --database.host=localhost). Supports arrays through comma-delimited values
141+
/// (e.g., --ports=8080,8081).
139142
struct Reader {
140143
using InputArrayType = CliArrayType;
141144
using InputObjectType = CliObjectType;
@@ -147,31 +150,32 @@ struct Reader {
147150
/// Gets a specific element from a CLI array by index.
148151
/// @param _idx The index of the element to retrieve
149152
/// @param _arr The CLI array
150-
/// @return A Result containing the element as a CliVarType or an error if out of bounds
153+
/// @return A Result containing the element as a CliVarType or an error if out
154+
/// of bounds
151155
rfl::Result<InputVarType> get_field_from_array(
152156
const size_t _idx, const InputArrayType& _arr) const noexcept {
153157
if (_idx >= _arr.values.size()) {
154-
return error(
155-
std::string("Index ") + std::to_string(_idx) + " out of bounds.");
158+
return error(std::string("Index ") + std::to_string(_idx) +
159+
" out of bounds.");
156160
}
157161
return InputVarType{nullptr, "", _arr.values[_idx]};
158162
}
159163

160164
/// Gets a specific field from a CLI object by name.
161-
/// Constructs a child path by appending the field name to the object's prefix.
165+
/// Constructs a child path by appending the field name to the object's
166+
/// prefix.
162167
/// @param _name The field name
163168
/// @param _obj The CLI object
164169
/// @return A Result containing a CliVarType for accessing the field
165170
rfl::Result<InputVarType> get_field_from_object(
166171
const std::string& _name, const InputObjectType& _obj) const noexcept {
167-
const auto child_path = _obj.prefix.empty()
168-
? _name
169-
: _obj.prefix + _name;
172+
const auto child_path = _obj.prefix.empty() ? _name : _obj.prefix + _name;
170173
return InputVarType{_obj.args, child_path, std::nullopt};
171174
}
172175

173176
/// Checks if a CLI variable is empty (has no value).
174-
/// A variable is empty if there's no direct value and no matching key in the argument map.
177+
/// A variable is empty if there's no direct value and no matching key in the
178+
/// argument map.
175179
/// @param _var The CLI variable to check
176180
/// @return true if the variable is empty, false otherwise
177181
bool is_empty(const InputVarType& _var) const noexcept {
@@ -186,23 +190,21 @@ struct Reader {
186190
}
187191
const auto prefix = _var.path + path_separator;
188192
const auto it = _var.args->lower_bound(prefix);
189-
return it == _var.args->end()
190-
|| it->first.substr(0, prefix.size()) != prefix;
193+
return it == _var.args->end() ||
194+
it->first.substr(0, prefix.size()) != prefix;
191195
}
192196

193197
/// Reads all elements from a CLI array using the provided array reader.
194-
/// @tparam ArrayReader The type of reader that processes individual array elements
198+
/// @tparam ArrayReader The type of reader that processes individual array
199+
/// elements
195200
/// @param _array_reader The reader object that processes each element
196201
/// @param _arr The CLI array to read from
197202
/// @return std::nullopt on success, or an Error if reading fails
198203
template <class ArrayReader>
199-
std::optional<Error> read_array(
200-
const ArrayReader& _array_reader,
201-
const InputArrayType& _arr
202-
) const noexcept {
204+
std::optional<Error> read_array(const ArrayReader& _array_reader,
205+
const InputArrayType& _arr) const noexcept {
203206
for (const auto& val : _arr.values) {
204-
const auto err = _array_reader.read(
205-
InputVarType{nullptr, "", val});
207+
const auto err = _array_reader.read(InputVarType{nullptr, "", val});
206208
if (err) {
207209
return err;
208210
}
@@ -211,36 +213,33 @@ struct Reader {
211213
}
212214

213215
/// Reads all fields from a CLI object using the provided object reader.
214-
/// Iterates through all arguments with the object's prefix and extracts child field names.
215-
/// @tparam ObjectReader The type of reader that processes individual object fields
216+
/// Iterates through all arguments with the object's prefix and extracts child
217+
/// field names.
218+
/// @tparam ObjectReader The type of reader that processes individual object
219+
/// fields
216220
/// @param _object_reader The reader object that processes each field
217221
/// @param _obj The CLI object to read from
218222
/// @return std::nullopt on success, or an Error if reading fails
219223
template <class ObjectReader>
220-
std::optional<Error> read_object(
221-
const ObjectReader& _object_reader,
222-
const InputObjectType& _obj
223-
) const noexcept {
224+
std::optional<Error> read_object(const ObjectReader& _object_reader,
225+
const InputObjectType& _obj) const noexcept {
224226
std::set<std::string> seen;
225-
auto it = _obj.prefix.empty()
226-
? _obj.args->begin()
227-
: _obj.args->lower_bound(_obj.prefix);
227+
auto it = _obj.prefix.empty() ? _obj.args->begin()
228+
: _obj.args->lower_bound(_obj.prefix);
228229
while (it != _obj.args->end()) {
229-
if (!_obj.prefix.empty()
230-
&& it->first.substr(0, _obj.prefix.size()) != _obj.prefix) {
230+
if (!_obj.prefix.empty() &&
231+
it->first.substr(0, _obj.prefix.size()) != _obj.prefix) {
231232
break;
232233
}
233234
const auto rest = std::string_view(it->first).substr(_obj.prefix.size());
234235
const auto separator_pos = rest.find(path_separator);
235-
const auto child = std::string(
236-
separator_pos == std::string_view::npos
237-
? rest
238-
: rest.substr(0, separator_pos));
236+
const auto child = std::string(separator_pos == std::string_view::npos
237+
? rest
238+
: rest.substr(0, separator_pos));
239239
if (!child.empty() && seen.insert(child).second) {
240240
const auto child_path = _obj.prefix + child;
241-
_object_reader.read(
242-
std::string_view(child),
243-
InputVarType{_obj.args, child_path, std::nullopt});
241+
_object_reader.read(std::string_view(child),
242+
InputVarType{_obj.args, child_path, std::nullopt});
244243
}
245244
++it;
246245
}
@@ -279,14 +278,12 @@ struct Reader {
279278
rfl::Result<InputObjectType> to_object(
280279
const InputVarType& _var) const noexcept {
281280
if (!_var.args) {
282-
return error("Cannot convert to object: no argument map available"
283-
+ (_var.path.empty()
284-
? std::string(".")
285-
: " for key '" + _var.path + "'."));
281+
return error("Cannot convert to object: no argument map available" +
282+
(_var.path.empty() ? std::string(".")
283+
: " for key '" + _var.path + "'."));
286284
}
287-
const auto prefix = _var.path.empty()
288-
? std::string("")
289-
: _var.path + path_separator;
285+
const auto prefix =
286+
_var.path.empty() ? std::string("") : _var.path + path_separator;
290287
return InputObjectType{_var.args, prefix};
291288
}
292289

@@ -295,16 +292,13 @@ struct Reader {
295292
/// @param _var The CLI variable (unused)
296293
/// @return Always returns an error
297294
template <class T>
298-
rfl::Result<T> use_custom_constructor(
299-
const InputVarType&
300-
) const noexcept {
295+
rfl::Result<T> use_custom_constructor(const InputVarType&) const noexcept {
301296
return error("Custom constructors are not supported for CLI parsing.");
302297
}
303298

304299
private:
305300
static std::optional<std::string> get_value(
306-
const InputVarType& _var
307-
) noexcept {
301+
const InputVarType& _var) noexcept {
308302
if (_var.direct_value) {
309303
return *_var.direct_value;
310304
}
@@ -318,9 +312,7 @@ struct Reader {
318312
return it->second;
319313
}
320314

321-
static std::vector<std::string> split(
322-
const std::string& _str, char _delim
323-
) {
315+
static std::vector<std::string> split(const std::string& _str, char _delim) {
324316
std::vector<std::string> result;
325317
if (_str.empty()) {
326318
return result;
@@ -341,7 +333,6 @@ struct Reader {
341333
}
342334
return result;
343335
}
344-
345336
};
346337

347338
} // namespace rfl::cli

0 commit comments

Comments
 (0)