Yerbacon/src/headers/arguments.hpp

62 lines
2.2 KiB
C++

#ifndef YERBACON_ARGUMENTS_HPP
#define YERBACON_ARGUMENTS_HPP
#include <iostream>
#include <utility>
#include <string>
#include <string_view>
#include <span>
using namespace std;
class Argument {
protected:
const string longVersion;
virtual bool is(string_view str) {
bool hasPrefix = str.starts_with("--");
if (hasPrefix) str.remove_prefix(2);
return (not str.empty()) && longVersion == str && hasPrefix;
}
public:
bool operator ==(const string_view it) { return is(it); }
explicit Argument(string name): longVersion(move(name)) {}
};
class ArgumentAssignable: public Argument {
vector<string_view> values;
public:
static string getValueFor(const string& str) {
unsigned long definePos = str.find_last_of('=') + 1;
return str.size() > definePos ? str.substr(definePos) : string();
}
ArgumentAssignable(string name, const span<string_view>& possibleValues) : Argument(move(name)), values() {
values.reserve(possibleValues.size());
move(possibleValues.begin(), possibleValues.end(), back_inserter(values));
}
explicit ArgumentAssignable(const string& name): ArgumentAssignable(name, span<string_view>()) {}; // To use when we don't want the argument's possible values to be checked
protected:
bool is(string_view str) override {
if (str.find_last_of('=') != string_view::npos && !str.empty()) {
auto isValid = [&]() -> bool { return str.starts_with("--" + longVersion + '='); };
if (values.empty()) return isValid();
for (const auto& value : values) {
if (str.ends_with(value.substr(1, value.size()))) {
return isValid();
}
}
}
return false;
}
};
struct ArgumentShort: public Argument {
const string shortVersion;
ArgumentShort(string shortName, string name): Argument(move(name)), shortVersion(move(shortName)) {}
explicit ArgumentShort(string name): ArgumentShort(string(1, name.at(0)), name) {}
protected:
bool is(string_view string) override {
return Argument::is(string) || (!string.empty() && shortVersion == string.substr(1, string.size()));
}
};
#endif //YERBACON_ARGUMENTS_HPP