mirror of
https://git.lynn.is/Gwen/argparser.git
synced 2024-04-29 12:23:46 +02:00
85 lines
2.5 KiB
C++
85 lines
2.5 KiB
C++
#ifndef ARGPARSER_SINGLE_OPT_H
|
|
#define ARGPARSER_SINGLE_OPT_H
|
|
|
|
#include <cassert>
|
|
#include <format>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <string>
|
|
|
|
#include "option.h"
|
|
#include "parse-result.h"
|
|
#include "type.h"
|
|
|
|
namespace argparser {
|
|
|
|
template<typename T>
|
|
class option_impl : public option, public std::enable_shared_from_this<option_impl<T>> {
|
|
public:
|
|
option_impl(std::string name, type_handle_impl<T> type) : option(std::move(name)), type(std::move(type)) {}
|
|
|
|
std::shared_ptr<option_impl<T>> required() {
|
|
required_ = true;
|
|
return this->shared_from_this();
|
|
}
|
|
|
|
std::shared_ptr<option_impl<T>> default_value(T val) {
|
|
this->default_value_ = val;
|
|
this->has_default_value = true;
|
|
return this->shared_from_this();
|
|
}
|
|
|
|
void validate(const parse_result &res) const override {
|
|
if (this->required_) {
|
|
if (!res.has_opt(this->name)) {
|
|
throw errors::missing_option_error(this->name);
|
|
}
|
|
}
|
|
}
|
|
|
|
[[nodiscard]] bool consumes_value() const override {
|
|
return true;
|
|
}
|
|
|
|
[[nodiscard]] T get(const parse_result &pr) const {
|
|
auto v = pr.get_opt(name);
|
|
if (!v.has_value()) {
|
|
if (has_default_value) {
|
|
return default_value_;
|
|
}
|
|
throw std::runtime_error(std::format("option {} was not provided", name));
|
|
}
|
|
return std::any_cast<T>(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());
|
|
const char *parse_end;
|
|
auto begin = &*arg->begin();
|
|
auto end = &*arg->end();
|
|
val = this->type->parse(begin, end, parse_end, internal::parser_allow_undelimited::Any);
|
|
if (parse_end != end) {
|
|
throw errors::type_parsing_error(this->type->get_name(), std::string(begin, end), parse_end - begin, "unexpected input");
|
|
}
|
|
}
|
|
|
|
type_handle_impl<T> type;
|
|
|
|
bool required_ = false;
|
|
|
|
bool has_default_value = false;
|
|
T default_value_;
|
|
};
|
|
|
|
template<typename T>
|
|
using option_handle_impl = std::shared_ptr<option_impl<T>>;
|
|
|
|
}// namespace argparser
|
|
|
|
#endif//ARGPARSER_SINGLE_OPT_H
|