validator.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #pragma once
  2. #include <jvalidate/forward.h>
  3. #include <jvalidate/regex.h>
  4. #include <jvalidate/status.h>
  5. #include <jvalidate/validation_config.h>
  6. #include <jvalidate/validation_visitor.h>
  7. namespace jvalidate::detail {
  8. /**
  9. * @brief An implementation of an "Extension Constraint Visitor" plugin that
  10. * does nothing.
  11. */
  12. struct StubExtensionVisitor {};
  13. }
  14. namespace jvalidate {
  15. /**
  16. * @brief A validator is the tool by which a JSON object is actually validated
  17. * against a schema.
  18. *
  19. * @tparam RE A type that can be used to solve regular expressions
  20. */
  21. template <RegexEngine RE = JVALIDATE_IIF(JVALIDATE_HAS_ICU, ICURegexEngine, StdRegexEngine),
  22. typename ExtensionVisitor = detail::StubExtensionVisitor>
  23. class Validator {
  24. private:
  25. schema::Node const & schema_;
  26. ValidationConfig cfg_;
  27. ExtensionVisitor extension_;
  28. RE regex_;
  29. public:
  30. /**
  31. * @brief Construct a Validator
  32. *
  33. * @param schema The root schema being validated against. Must outlive this.
  34. *
  35. * @param cfg Any special (runtime) configuration rules being applied to the
  36. * validator.
  37. */
  38. Validator(schema::Node const & schema, ExtensionVisitor extension = {},
  39. ValidationConfig const & cfg = {})
  40. : schema_(schema), cfg_(cfg), extension_(extension) {}
  41. Validator(schema::Node const & schema, ValidationConfig const & cfg)
  42. : schema_(schema), cfg_(cfg) {}
  43. template <typename... Args> Validator(schema::Node &&, Args &&...) = delete;
  44. /**
  45. * @brief Run validation on the given JSON
  46. *
  47. * @tparam A Any Adapter type, in principle a subclass of adapter::Adapter.
  48. * Disallows mutation via ValidationConfig.construct_default_values
  49. *
  50. * @param json The value being validated
  51. *
  52. * @param result An optional out-param of detailed information about
  53. * validation failures. If result is not provided, then the validator will
  54. * terminate on the first error. Otherwise it will run through the entire
  55. * schema to provide a record of all of the failures.
  56. */
  57. template <Adapter A>
  58. requires(not MutableAdapter<A>)
  59. bool validate(A const & json, ValidationResult * result = nullptr) {
  60. EXPECT_M(not cfg_.construct_default_values,
  61. "Cannot perform mutations on an immutable JSON Adapter");
  62. return static_cast<bool>(
  63. ValidationVisitor(schema_, cfg_, regex_, extension_, result).validate(json));
  64. }
  65. /**
  66. * @brief Run validation on the given JSON
  67. *
  68. * @tparam A Any Adapter type that supports assignment, in principle a
  69. * subclass of adapter::Adapter.
  70. *
  71. * @param json The value being validated. Because A is a reference-wrapper,
  72. * the underlying value may be mutated.
  73. *
  74. * @param result An optional out-param of detailed information about
  75. * validation failures. If result is not provided, then the validator will
  76. * terminate on the first error. Otherwise it will run through the entire
  77. * schema to provide a record of all of the failures.
  78. */
  79. template <MutableAdapter A> bool validate(A const & json, ValidationResult * result = nullptr) {
  80. return static_cast<bool>(
  81. ValidationVisitor(schema_, cfg_, regex_, extension_, result).validate(json));
  82. }
  83. /**
  84. * @brief Run validation on the given JSON
  85. *
  86. * @tparam JSON A concrete JSON type. Will be turned into an Adapter, or a
  87. * MutableAdapter (if json is non-const and exists).
  88. *
  89. * @param json The value being validated.
  90. *
  91. * @param result An optional out-param of detailed information about
  92. * validation failures. If result is not provided, then the validator will
  93. * terminate on the first error. Otherwise it will run through the entire
  94. * schema to provide a record of all of the failures.
  95. */
  96. template <typename JSON>
  97. requires(not Adapter<JSON>)
  98. bool validate(JSON & json, ValidationResult * result = nullptr) {
  99. return validate(adapter::AdapterFor<JSON>(json), result);
  100. }
  101. };
  102. }