argparser/src/errors.h
2023-05-17 10:17:56 +02:00

117 lines
5.4 KiB
C++

#ifndef ARGPARSER_ERRORS_H
#define ARGPARSER_ERRORS_H
#include <format>
#include <optional>
#include <stdexcept>
#include <string>
#include <vector>
namespace argparser::errors {
class runtime_error : public std::runtime_error {
public:
template<typename... Ts>
explicit runtime_error(Ts... args) : std::runtime_error(args...) {}
};
class logic_error : public std::logic_error {
public:
template<typename... Ts>
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<unsigned int> min, std::optional<unsigned int> 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<unsigned int> min, std::optional<unsigned int> 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<std::string> possible_types)
: type_parsing_error(type_name, input, error_pos, make_message(possible_types)) {}
private:
static std::string make_message(std::vector<std::string> 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