#pragma once
|
|
#include "UserScript.h"
|
|
#include "UserScriptWizardry.h"
|
|
#include <concepts>
|
|
#include <span>
|
|
#include <ranges>
|
|
|
|
/*template<size_t arg_number>
|
|
struct verifier_base {
|
|
static constexpr size_t argument_id = arg_number;
|
|
};*/
|
|
|
|
namespace details {
|
|
template<size_t argument_counter, typename T>
|
|
struct TypeVerifier {
|
|
static constexpr size_t argument_id = argument_counter;
|
|
|
|
bool verify(scripting::UserScript* self, std::vector<scripting::argument>& args) {
|
|
if(argument_id >= args.size()) return false;
|
|
if(args.size() -1 -argument_id < 0) return false;
|
|
auto& argument = args[args.size() -1 -argument_id];
|
|
std::optional<std::reference_wrapper<scripting::script_value>> v = std::visit(
|
|
wizardry::overloaded{
|
|
[&](scripting::script_variable& v) -> std::optional<std::reference_wrapper<scripting::script_value>> {return self->getValue(v.name);},
|
|
[&](scripting::script_value& v) -> std::optional<std::reference_wrapper<scripting::script_value>> {return v;},
|
|
},
|
|
argument
|
|
);
|
|
if(not v) return false;
|
|
return std::visit(wizardry::overloaded{
|
|
[](T& ) {return true;},
|
|
[](auto&) {return false;}
|
|
}, v.value().get());
|
|
}
|
|
};
|
|
template<size_t argument_counter>
|
|
struct VariableVerifier {
|
|
static constexpr size_t argument_id = argument_counter;
|
|
|
|
bool verify(scripting::UserScript* self, std::vector<scripting::argument>& args) {
|
|
if(argument_id >= args.size()) return false;
|
|
if(args.size() -1 -argument_id < 0) return false;
|
|
auto& argument = args[args.size() -1 -argument_id];
|
|
return std::visit(
|
|
wizardry::overloaded{
|
|
[&](scripting::script_variable& v) -> bool {return self->getValue(v.name).has_value();},
|
|
[&](scripting::script_value& v) {return false;},
|
|
},
|
|
argument
|
|
);
|
|
}
|
|
};
|
|
|
|
template<size_t skip = 0>
|
|
struct NoArrays {
|
|
bool verify(scripting::UserScript* self, std::vector<scripting::argument> args) {
|
|
for(auto& elem : std::ranges::reverse_view(args) | std::ranges::views::drop(skip)) {
|
|
std::optional<std::reference_wrapper<scripting::script_value>> v;
|
|
std::visit(
|
|
wizardry::overloaded{
|
|
[&](scripting::script_variable& n) {v = self->getValue(n.name);},
|
|
[&](scripting::script_value& n) {v = n;},
|
|
},
|
|
elem
|
|
);
|
|
if(not v) return false;
|
|
if(std::visit(wizardry::overloaded{
|
|
[](scripting::array&) {return true;},
|
|
[](auto&) {return false;}
|
|
}, v.value().get())) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
template<size_t sz = 0>
|
|
struct SizeEquals {
|
|
bool verify(scripting::UserScript*, std::vector<scripting::argument> args) {
|
|
return args.size() == sz;
|
|
}
|
|
};
|
|
|
|
template<size_t sz = 0>
|
|
struct SizeAtLeast {
|
|
bool verify(scripting::UserScript*, std::vector<scripting::argument> args) {
|
|
return args.size() >= sz;
|
|
}
|
|
};
|
|
|
|
template<size_t argument_counter>
|
|
struct OctetArrayVerifier {
|
|
static constexpr size_t argument_id = argument_counter;
|
|
|
|
bool verify(scripting::UserScript* self, std::vector<scripting::argument>& args) {
|
|
if(argument_id >= args.size()) return false;
|
|
if(args.size() -1 -argument_id < 0) return false;
|
|
auto& argument = args[args.size() -1 -argument_id];
|
|
std::optional<std::reference_wrapper<scripting::script_value>> v;
|
|
std::visit(
|
|
wizardry::overloaded{
|
|
[&](scripting::script_variable& elem) {v = self->getValue(elem.name);},
|
|
[&](scripting::script_value& elem) {v = elem;}
|
|
},
|
|
argument
|
|
);
|
|
if(not v) return false;
|
|
return std::visit(
|
|
wizardry::overloaded{
|
|
[](scripting::array& ary) -> bool {
|
|
for(auto& elem : ary.value) {
|
|
if(std::holds_alternative<int32_t>(elem)) {
|
|
if(auto& byte = std::get<int32_t>(elem); byte < 0 || byte > 255) {
|
|
return false;
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
},
|
|
[] (auto&) -> bool {return false;}
|
|
},
|
|
v.value().get()
|
|
);
|
|
}
|
|
};
|
|
}
|
|
|
|
template<typename... verifiers>
|
|
struct Verify;
|
|
|
|
template<typename n, typename... verifiers>
|
|
struct Verify<n, verifiers...> {
|
|
bool verify(scripting::UserScript* self, std::vector<scripting::argument>& args) {
|
|
return n{}.verify(self, args) && Verify<verifiers...>{}.verify(self, args);
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct Verify<> {
|
|
bool verify(scripting::UserScript*, const std::vector<scripting::argument>&) {
|
|
return true;
|
|
}
|
|
};
|
|
|