You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
4.2 KiB

  1. #pragma once
  2. #include "UserScript.h"
  3. #include "UserScriptWizardry.h"
  4. #include <concepts>
  5. #include <span>
  6. #include <ranges>
  7. /*template<size_t arg_number>
  8. struct verifier_base {
  9. static constexpr size_t argument_id = arg_number;
  10. };*/
  11. namespace details {
  12. template<size_t argument_counter, typename T>
  13. struct TypeVerifier {
  14. static constexpr size_t argument_id = argument_counter;
  15. bool verify(scripting::UserScript* self, std::vector<scripting::argument>& args) {
  16. if(argument_id >= args.size()) return false;
  17. if(args.size() -1 -argument_id < 0) return false;
  18. auto& argument = args[args.size() -1 -argument_id];
  19. std::optional<std::reference_wrapper<scripting::script_value>> v = std::visit(
  20. wizardry::overloaded{
  21. [&](scripting::script_variable& v) -> std::optional<std::reference_wrapper<scripting::script_value>> {return self->getValue(v.name);},
  22. [&](scripting::script_value& v) -> std::optional<std::reference_wrapper<scripting::script_value>> {return v;},
  23. },
  24. argument
  25. );
  26. if(not v) return false;
  27. return std::visit(wizardry::overloaded{
  28. [](T& ) {return true;},
  29. [](auto&) {return false;}
  30. }, v.value().get());
  31. }
  32. };
  33. template<size_t argument_counter>
  34. struct VariableVerifier {
  35. static constexpr size_t argument_id = argument_counter;
  36. bool verify(scripting::UserScript* self, std::vector<scripting::argument>& args) {
  37. if(argument_id >= args.size()) return false;
  38. if(args.size() -1 -argument_id < 0) return false;
  39. auto& argument = args[args.size() -1 -argument_id];
  40. return std::visit(
  41. wizardry::overloaded{
  42. [&](scripting::script_variable& v) -> bool {return self->getValue(v.name).has_value();},
  43. [&](scripting::script_value& v) {return false;},
  44. },
  45. argument
  46. );
  47. }
  48. };
  49. template<size_t skip = 0>
  50. struct NoArrays {
  51. bool verify(scripting::UserScript* self, std::vector<scripting::argument> args) {
  52. for(auto& elem : std::ranges::reverse_view(args) | std::ranges::views::drop(skip)) {
  53. std::optional<std::reference_wrapper<scripting::script_value>> v;
  54. std::visit(
  55. wizardry::overloaded{
  56. [&](scripting::script_variable& n) {v = self->getValue(n.name);},
  57. [&](scripting::script_value& n) {v = n;},
  58. },
  59. elem
  60. );
  61. if(not v) return false;
  62. if(std::visit(wizardry::overloaded{
  63. [](scripting::array&) {return true;},
  64. [](auto&) {return false;}
  65. }, v.value().get())) {
  66. return false;
  67. }
  68. }
  69. return true;
  70. }
  71. };
  72. template<size_t sz = 0>
  73. struct SizeEquals {
  74. bool verify(scripting::UserScript*, std::vector<scripting::argument> args) {
  75. return args.size() == sz;
  76. }
  77. };
  78. template<size_t sz = 0>
  79. struct SizeAtLeast {
  80. bool verify(scripting::UserScript*, std::vector<scripting::argument> args) {
  81. return args.size() >= sz;
  82. }
  83. };
  84. template<size_t argument_counter>
  85. struct OctetArrayVerifier {
  86. static constexpr size_t argument_id = argument_counter;
  87. bool verify(scripting::UserScript* self, std::vector<scripting::argument>& args) {
  88. if(argument_id >= args.size()) return false;
  89. if(args.size() -1 -argument_id < 0) return false;
  90. auto& argument = args[args.size() -1 -argument_id];
  91. std::optional<std::reference_wrapper<scripting::script_value>> v;
  92. std::visit(
  93. wizardry::overloaded{
  94. [&](scripting::script_variable& elem) {v = self->getValue(elem.name);},
  95. [&](scripting::script_value& elem) {v = elem;}
  96. },
  97. argument
  98. );
  99. if(not v) return false;
  100. return std::visit(
  101. wizardry::overloaded{
  102. [](scripting::array& ary) -> bool {
  103. for(auto& elem : ary.value) {
  104. if(std::holds_alternative<int32_t>(elem)) {
  105. if(auto& byte = std::get<int32_t>(elem); byte < 0 || byte > 255) {
  106. return false;
  107. }
  108. } else {
  109. return false;
  110. }
  111. }
  112. return true;
  113. },
  114. [] (auto&) -> bool {return false;}
  115. },
  116. v.value().get()
  117. );
  118. }
  119. };
  120. }
  121. template<typename... verifiers>
  122. struct Verify;
  123. template<typename n, typename... verifiers>
  124. struct Verify<n, verifiers...> {
  125. bool verify(scripting::UserScript* self, std::vector<scripting::argument>& args) {
  126. return n{}.verify(self, args) && Verify<verifiers...>{}.verify(self, args);
  127. }
  128. };
  129. template<>
  130. struct Verify<> {
  131. bool verify(scripting::UserScript*, const std::vector<scripting::argument>&) {
  132. return true;
  133. }
  134. };