|
|
@@ -44,10 +44,11 @@
|
|
|
} while (false)
|
|
|
|
|
|
namespace jvalidate {
|
|
|
-template <RegexEngine RE> class ValidationVisitor {
|
|
|
+template <RegexEngine RE, typename ExtensionVisitor> class ValidationVisitor {
|
|
|
private:
|
|
|
JVALIDATE_TRIBOOL_TYPE(StoreResults, ForValid, ForInvalid, ForAnything);
|
|
|
using VisitedAnnotation = std::tuple<std::unordered_set<size_t>, std::unordered_set<std::string>>;
|
|
|
+ friend ExtensionVisitor;
|
|
|
|
|
|
private:
|
|
|
detail::Pointer where_;
|
|
|
@@ -58,6 +59,7 @@ private:
|
|
|
ValidationResult * result_;
|
|
|
|
|
|
ValidationConfig const & cfg_;
|
|
|
+ ExtensionVisitor extension_;
|
|
|
RE & regex_;
|
|
|
|
|
|
mutable VisitedAnnotation * visited_ = nullptr;
|
|
|
@@ -71,12 +73,22 @@ public:
|
|
|
* @param cfg General configuration settings for how the run is executed
|
|
|
* @param regex A cache of string regular expressions to compiled
|
|
|
* regular expressions
|
|
|
+ * @param[optional] extension A special visitor for extension constraints.
|
|
|
* @param[optional] result A cache of result/annotation info for the user to
|
|
|
* receive a detailed summary of why a document is supported/unsupported.
|
|
|
*/
|
|
|
ValidationVisitor(schema::Node const & schema, ValidationConfig const & cfg, RE & regex,
|
|
|
- ValidationResult * result)
|
|
|
- : schema_(&schema), result_(result), cfg_(cfg), regex_(regex) {}
|
|
|
+ ExtensionVisitor extension, ValidationResult * result)
|
|
|
+ : schema_(&schema), result_(result), cfg_(cfg), extension_(extension), regex_(regex) {}
|
|
|
+
|
|
|
+ Status visit(constraint::ExtensionConstraint const & cons, Adapter auto const & document) const {
|
|
|
+ if constexpr (std::is_invocable_r_v<Status, ExtensionVisitor, decltype(cons),
|
|
|
+ decltype(document), ValidationVisitor const &>) {
|
|
|
+ return extension_(cons, document, *this);
|
|
|
+ }
|
|
|
+ annotate("unsupported extension");
|
|
|
+ return Status::Noop;
|
|
|
+ }
|
|
|
|
|
|
Status visit(constraint::TypeConstraint const & cons, Adapter auto const & document) const {
|
|
|
adapter::Type const type = document.type();
|
|
|
@@ -96,10 +108,6 @@ public:
|
|
|
return result(Status::Reject, type, " is not in types [", cons.types, "]");
|
|
|
}
|
|
|
|
|
|
- Status visit(constraint::ExtensionConstraint const & cons, Adapter auto const & document) const {
|
|
|
- // return cons.validate(document, where_, result_);
|
|
|
- }
|
|
|
-
|
|
|
Status visit(constraint::EnumConstraint const & cons, Adapter auto const & document) const {
|
|
|
auto is_equal = [this, &document](auto const & frozen) {
|
|
|
return document.equals(frozen, cfg_.strict_equality);
|