Pārlūkot izejas kodu

feat: allow filtering output by only returning errors

Sam Jaffe 3 nedēļas atpakaļ
vecāks
revīzija
e76d891557

+ 4 - 0
include/jvalidate/validation_config.h

@@ -20,5 +20,9 @@ struct ValidationConfig {
   // When enabled, we will validate format constraints on the document, instead
   // of using them purely as annotations.
   bool validate_format = false;
+
+  // When enabled, will filter out any elements of the ValidationResult which
+  // contain only annotations.
+  bool only_return_results_with_error = false;
 };
 }

+ 20 - 5
include/jvalidate/validation_result.h

@@ -214,6 +214,21 @@ public:
     return &local.errors.at(name);
   }
 
+  ValidationResult only_errors() const {
+    ValidationResult rval;
+    rval.valid_ = valid_;
+
+    for (auto const & [doc, results] : results_) {
+      for (auto const & [schema, result] : results) {
+        if (!result.valid && !result.errors.empty()) {
+          rval.results_[doc][schema] = result;
+        }
+      }
+    }
+
+    return rval;
+  }
+
 private:
   /**
    * @brief Transfer the contents of another ValidationResult into this one using
@@ -263,7 +278,7 @@ private:
     if (std::visit([](auto const & v) { return v.empty(); }, message)) {
       return;
     }
-    std::visit([](auto &msg) { sanitize(msg); }, message);
+    std::visit([](auto & msg) { sanitize(msg); }, message);
     results_[where][schema_path].errors.emplace(name, std::move(message));
   }
 
@@ -281,11 +296,11 @@ private:
     if (std::visit([](auto const & v) { return v.empty(); }, message)) {
       return;
     }
-    std::visit([](auto &msg) { sanitize(msg); }, message);
+    std::visit([](auto & msg) { sanitize(msg); }, message);
     results_[where][schema_path].annotations.emplace(name, std::move(message));
   }
 
-  static void sanitize(std::string &message) {
+  static void sanitize(std::string & message) {
     for (auto it = message.begin(); it != message.end(); ++it) {
       if (*it == '"' || *it == '\\') {
         it = ++message.insert(it, '\\');
@@ -293,8 +308,8 @@ private:
     }
   }
 
-  static void sanitize(std::vector<std::string> &message) {
-    std::ranges::for_each(message, [](std::string &val) { sanitize(val); });
+  static void sanitize(std::vector<std::string> & message) {
+    std::ranges::for_each(message, [](std::string & val) { sanitize(val); });
   }
 };
 }

+ 13 - 0
include/jvalidate/validator.h

@@ -3,6 +3,7 @@
 #include <regex>
 #include <unordered_map>
 
+#include <jvalidate/detail/on_block_exit.h>
 #include <jvalidate/forward.h>
 #include <jvalidate/status.h>
 #include <jvalidate/validation_config.h>
@@ -92,6 +93,7 @@ public:
   bool validate(A const & json, ValidationResult * result = nullptr) {
     EXPECT_M(not cfg_.construct_default_values,
              "Cannot perform mutations on an immutable JSON Adapter");
+    detail::OnBlockExit _ = [&result, this]() { post_process(result); };
     return static_cast<bool>(
         ValidationVisitor(schema_, cfg_, regex_, extension_, result).validate(json));
   }
@@ -111,6 +113,7 @@ public:
    * schema to provide a record of all of the failures.
    */
   template <MutableAdapter A> bool validate(A const & json, ValidationResult * result = nullptr) {
+    detail::OnBlockExit _ = [&result, this]() { post_process(result); };
     return static_cast<bool>(
         ValidationVisitor(schema_, cfg_, regex_, extension_, result).validate(json));
   }
@@ -133,5 +136,15 @@ public:
   bool validate(JSON & json, ValidationResult * result = nullptr) {
     return validate(adapter::AdapterFor<JSON>(json), result);
   }
+
+private:
+  void post_process(ValidationResult *& result) const {
+    if (result == nullptr) {
+      return;
+    }
+    if (cfg_.only_return_results_with_error) {
+      *result = result->only_errors();
+    }
+  }
 };
 }

+ 2 - 1
src/validate.cxx

@@ -85,7 +85,8 @@ int main(int argc, char const * const * argv) {
   jvalidate::Schema schema(jschema, Draft2020_12, &curl_get);
 
   jvalidate::ValidationResult result;
-  if (!jvalidate::Validator(schema).validate(jobject, &result)) {
+  if (!jvalidate::Validator(schema, {.only_return_results_with_error = true})
+           .validate(jobject, &result)) {
     std::cout << result;
   }