34 #ifndef VP_JSON_ARGUMENT_PARSER_H
35 #define VP_JSON_ARGUMENT_PARSER_H
37 #include <visp3/core/vpConfig.h>
39 #if defined(VISP_HAVE_NLOHMANN_JSON)
40 #include VISP_NLOHMANN_JSON(json.hpp)
41 #include <visp3/core/vpException.h>
53 nlohmann::json convertCommandLineArgument(
const std::string &arg)
55 nlohmann::json j = nlohmann::json::parse(arg);
66 nlohmann::json convertCommandLineArgument<std::string>(
const std::string &arg)
68 nlohmann::json j = arg;
163 vpJsonArgumentParser(
const std::string &description,
const std::string &jsonFileArgumentName,
const std::string &nestSeparator);
172 std::string help()
const;
191 argumentType[name] = WITH_FIELD;
192 const auto getter = [name,
this](nlohmann::json &j,
bool create) -> nlohmann::json * {
194 nlohmann::json *f = &j;
196 std::string name_copy = name;
198 while ((pos = name_copy.find(nestSeparator)) != std::string::npos) {
199 token = name_copy.substr(0, pos);
201 name_copy.erase(0, pos + nestSeparator.length());
202 if (create && !f->contains(token)) {
205 else if (!f->contains(token)) {
210 if (create && !f->contains(name_copy)) {
211 (*f)[name_copy] = {};
213 else if (!f->contains(name_copy)) {
216 f = &(f->at(name_copy));
220 parsers[name] = [¶meter, required, getter, name](nlohmann::json &j) {
221 const nlohmann::json *field = getter(j,
false);
222 const bool fieldHasNoValue = field ==
nullptr || (field !=
nullptr && field->is_null());
223 if (required && fieldHasNoValue) {
224 std::stringstream ss;
225 ss <<
"Argument " << name <<
" is required, but no value was provided" << std::endl;
228 else if (!fieldHasNoValue) {
229 field->get_to(parameter);
233 updaters[name] = [getter](nlohmann::json &j,
const std::string &s) {
234 nlohmann::json *field = getter(j,
true);
235 *field = convertCommandLineArgument<T>(s);
238 helpers[name] = [help, parameter, required]() -> std::string {
239 std::stringstream ss;
240 nlohmann::json repr = parameter;
241 ss << help << std::endl <<
"Default: " << repr;
243 ss << std::endl <<
"Required";
246 ss << std::endl <<
"Optional";
251 nlohmann::json *exampleField = getter(exampleJson,
true);
252 *exampleField = parameter;
266 vpJsonArgumentParser &addFlag(
const std::string &name,
bool ¶meter,
const std::string &help =
"No description");
274 void parse(
int argc,
const char *argv[]);
277 std::string description;
278 std::string jsonFileArgumentName;
279 std::string nestSeparator;
280 std::map<std::string, std::function<void(nlohmann::json &)>> parsers;
281 std::map<std::string, vpJsonArgumentType> argumentType;
282 std::map<std::string, std::function<void(nlohmann::json &,
const std::string &)>> updaters;
283 std::map<std::string, std::function<std::string()>> helpers;
284 nlohmann::json exampleJson;
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
Command line argument parsing with support for JSON files. If a JSON file is supplied,...
vpJsonArgumentParser & addArgument(const std::string &name, T ¶meter, const bool required=true, const std::string &help="No description")
Add an argument that can be provided by the user, either via command line or through the json file.