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

73 lines
2.1 KiB
C++

#ifndef ARGPARSER_REPEAT_FLAG_H
#define ARGPARSER_REPEAT_FLAG_H
#include <cassert>
#include <memory>
#include <optional>
#include <string>
#include "errors.h"
#include "option.h"
#include "parse-result.h"
#include "type.h"
namespace argparser {
class repeatable_flag_impl : public option, public std::enable_shared_from_this<repeatable_flag_impl> {
public:
repeatable_flag_impl(std::string name) : option(std::move(name)) {}
std::shared_ptr<repeatable_flag_impl> min(unsigned int min) {
min_ = min;
return this->shared_from_this();
}
std::shared_ptr<repeatable_flag_impl> max(unsigned int max) {
max_ = max;
return this->shared_from_this();
}
[[nodiscard]] bool consumes_value() const override {
return false;
}
void validate(const parse_result &pr) const override {
unsigned int count = get(pr);
if ((min_.has_value() && count < min_.value()) ||
(max_.has_value() && count > max_.value())) {
throw errors::wrong_option_count_error(this->name, min_, max_, count);
}
}
[[nodiscard]] unsigned int get(const parse_result &pr) const {
auto v = pr.get_opt(name);
if (!v.has_value()) {
return 0;
}
return std::any_cast<unsigned int>(v);
}
[[nodiscard]] bool has(const parse_result &pr) const {
return pr.has_opt(name);
}
private:
void do_parse(std::optional<std::string> arg, std::any &val) override {
assert(!arg.has_value());
unsigned int count = 0;
if (val.has_value()) {
count = std::any_cast<unsigned int>(val);
}
val = std::make_any<unsigned int>(count + 1);
}
std::optional<unsigned int> min_ = std::nullopt;
std::optional<unsigned int> max_ = std::nullopt;
};
using repeatable_flag_handle_impl = std::shared_ptr<repeatable_flag_impl>;
}// namespace argparser
#endif//ARGPARSER_REPEAT_FLAG_H