#ifndef ARGPARSER_ERRORS_H #define ARGPARSER_ERRORS_H #include #include #include #include #include namespace argparser::errors { class runtime_error : public std::runtime_error { public: template explicit runtime_error(Ts... args) : std::runtime_error(args...) {} }; class logic_error : public std::logic_error { public: template explicit logic_error(Ts... args) : std::logic_error(args...) {} }; class missing_option_error : public runtime_error { public: explicit missing_option_error(std::string option_name) : runtime_error(std::format("missing required option {}", option_name)) {} }; class missing_argument_error : public runtime_error { public: explicit missing_argument_error(std::string arg_name) : runtime_error(std::format("missing argument {}", arg_name)) {} }; class unknown_option_error : public runtime_error { public: explicit unknown_option_error(std::string option_name) : runtime_error(std::format("unknown option {}", option_name)) {} }; class wrong_option_count_error : public runtime_error { public: wrong_option_count_error(const std::string &option_name, std::optional min, std::optional max, unsigned int actual) : runtime_error(make_message(option_name, min, max, actual)) {} private: static std::string make_message(std::string option_name, std::optional min, std::optional max, unsigned int actual) { if (min != std::nullopt && max != std::nullopt) { return std::format("option {} was provided {} times, but is required at least {} times and at most {} times", option_name, actual, min.value(), max.value()); } else if (min != std::nullopt) { return std::format("option {} was provided {} times, but is required at least {} times", option_name, actual, min.value()); } else { return std::format("option {} was provided {} times, but is required at most {} times", option_name, actual, max.value()); } } }; class missing_option_value_error : public runtime_error { public: explicit missing_option_value_error(std::string option_name) : runtime_error(std::format("missing value for option {}", option_name)) {} }; class not_enough_arguments_error : public runtime_error { public: explicit not_enough_arguments_error(size_t min_required) : runtime_error(std::format("not enough arguments, need at least {}", min_required)) {} }; class too_many_arguments_error : public runtime_error { public: explicit too_many_arguments_error() : runtime_error("too many arguments") {} }; class invalid_option_value_error : public runtime_error { public: explicit invalid_option_value_error(std::string option_name) : runtime_error(std::format("invalid value for option {}", option_name)) {} }; class unexpected_option_value_error : public runtime_error { public: explicit unexpected_option_value_error(std::string option_name) : runtime_error(std::format("unexpected value for option {}", option_name)) {} }; class type_parsing_error : public runtime_error { public: type_parsing_error(std::string type_name, std::string input, size_t error_pos, std::string message) : runtime_error(std::format("error parsing type {} at position {}: {}", type_name, error_pos, message)), type_name(type_name), input(input), error_pos(error_pos) {} const std::string type_name; const std::string input; const int error_pos; }; class ambiguous_parse_error : public type_parsing_error { public: explicit ambiguous_parse_error(std::string type_name, std::string input, size_t error_pos, std::vector possible_types) : type_parsing_error(type_name, input, error_pos, make_message(possible_types)) {} private: static std::string make_message(std::vector possible_types) { std::string message = "ambiguity between "; for (auto it = possible_types.begin(); it != possible_types.end(); it++) { if (std::next(it) == possible_types.end()) { message += " and " + *it; } else { message += ", " + *it; } } return message; } }; class invalid_option_name_error : public logic_error { public: explicit invalid_option_name_error(std::string option_name) : logic_error(std::format("invalid option name {}", option_name)) {} }; class duplicate_option_name : public logic_error { public: explicit duplicate_option_name(std::string option_name) : logic_error(std::format("option with name {} already exists", option_name)) {} }; class duplicate_argument_name : public logic_error { public: explicit duplicate_argument_name(std::string arg_name) : logic_error(std::format("argument with name {} already exists", arg_name)) {} }; class empty_enum_map_error : public logic_error { public: explicit empty_enum_map_error(std::string type_name) : logic_error(std::format("no enum values for type {}", type_name)) {} }; }// namespace argparser::errors #endif//ARGPARSER_ERRORS_H