validator.h 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #pragma once
  2. #include <regex>
  3. #include <unordered_map>
  4. #include <jvalidate/forward.h>
  5. #include <jvalidate/status.h>
  6. #include <jvalidate/validation_config.h>
  7. #include <jvalidate/validation_visitor.h>
  8. namespace jvalidate::detail {
  9. class StdRegexEngine {
  10. public:
  11. std::regex regex_;
  12. public:
  13. StdRegexEngine(std::string const & regex) : regex_(detail::regex_escape(regex)) {}
  14. bool search(std::string const & text) const { return std::regex_search(text, regex_); }
  15. static bool is_valid(std::string const & regex) {
  16. try {
  17. std::regex{regex};
  18. return true;
  19. } catch (...) { return false; }
  20. }
  21. };
  22. }
  23. namespace jvalidate {
  24. template <RegexEngine RE = detail::StdRegexEngine> class ValidatorT {
  25. private:
  26. schema::Node const & schema_;
  27. ValidationConfig cfg_;
  28. std::unordered_map<std::string, RE> regex_cache_;
  29. public:
  30. ValidatorT(schema::Node const & schema, ValidationConfig const & cfg = {})
  31. : schema_(schema), cfg_(cfg) {}
  32. template <Adapter A>
  33. requires(not MutableAdapter<A>) bool validate(A const & json,
  34. ValidationResult * result = nullptr) {
  35. EXPECT_M(not cfg_.construct_default_values,
  36. "Cannot perform mutations on an immutable JSON Adapter");
  37. return static_cast<bool>(
  38. ValidationVisitor<A, RE>(json, schema_, cfg_, regex_cache_, result).validate());
  39. }
  40. template <MutableAdapter A> bool validate(A const & json, ValidationResult * result = nullptr) {
  41. return static_cast<bool>(
  42. ValidationVisitor<A, RE>(json, schema_, cfg_, regex_cache_, result).validate());
  43. }
  44. template <typename JSON>
  45. requires(not Adapter<JSON>) bool validate(JSON & json, ValidationResult * result = nullptr) {
  46. return validate(adapter::AdapterFor<JSON>(json), result);
  47. }
  48. };
  49. class Validator : public ValidatorT<> {
  50. public:
  51. using Validator::ValidatorT::ValidatorT;
  52. };
  53. }