瀏覽代碼

refactor: implement required-keywords

Sam Jaffe 3 月之前
父節點
當前提交
357f676d91
共有 3 個文件被更改,包括 18 次插入10 次删除
  1. 2 0
      include/jvalidate/constraint.h
  2. 11 9
      include/jvalidate/detail/reference_manager.h
  3. 5 1
      include/jvalidate/detail/vocabulary.h

+ 2 - 0
include/jvalidate/constraint.h

@@ -126,10 +126,12 @@ private:
       {"items",
        {{schema::Version::Earliest, {&Self::itemsTupleOrVector, Keyword}},
         {schema::Version::Draft2020_12, {&Self::additionalItems, Keyword}}}},
+      {"maxContains", {schema::Version::Draft06, Literal}},
       {"maxItems", &Self::maxItems},
       {"maxLength", &Self::maxLength},
       {"maxProperties", {schema::Version::Draft04, &Self::maxProperties}},
       {"maximum", &Self::maximum},
+      {"minContains", {schema::Version::Draft06, Literal}},
       {"minItems", &Self::minItems},
       {"minLength", &Self::minLength},
       {"minProperties", {schema::Version::Draft04, &Self::minProperties}},

+ 11 - 9
include/jvalidate/detail/reference_manager.h

@@ -459,20 +459,22 @@ private:
    * - The list of enabled vocabulary metaschema (used for is_format_assertion)
    */
   auto extract_keywords(ObjectAdapter auto const & vocabularies) const
-      -> std::pair<std::unordered_set<std::string>, std::unordered_set<std::string>> {
-    std::unordered_set<std::string> keywords;
+      -> std::pair<std::unordered_map<std::string, bool>, std::unordered_set<std::string>> {
+    std::unordered_map<std::string, bool> keywords;
     std::unordered_set<std::string> vocab_docs;
-    for (auto [vocab, enabled] : vocabularies) {
-      if (not enabled.as_boolean()) {
-        continue;
-      }
-
+    for (auto [vocab, required] : vocabularies) {
       size_t n = vocab.find("/vocab/");
       vocab_docs.emplace(vocab.substr(n));
       vocab.replace(n, 7, "/meta/");
+
       auto vocab_object = external_.try_load(URI(vocab));
-      for (auto const & [keyword, _] : vocab_object->as_object()["properties"].as_object()) {
-        keywords.insert(keyword);
+      auto it = vocab_object->as_object().find("properties");
+      if (it == vocab_object->as_object().end()) {
+        continue;
+      }
+
+      for (auto const & [keyword, _] : it->second.as_object()) {
+        keywords.emplace(keyword, required.as_boolean());
       }
     }
     return std::make_pair(keywords, vocab_docs);

+ 5 - 1
include/jvalidate/detail/vocabulary.h

@@ -38,7 +38,7 @@ public:
    * @param vocabularies An optional selection of vocabulary schemas, used
    * as metadata, and deducing {@see is_format_assertion}.
    */
-  void restrict(std::unordered_set<std::string> const & permitted_keywords,
+  void restrict(std::unordered_map<std::string, bool> const & permitted_keywords,
                 std::unordered_set<std::string> const & vocabularies = {}) & {
     permitted_.clear();
     vocabularies_ = vocabularies;
@@ -49,6 +49,10 @@ public:
         permitted_.insert(keyword);
       }
     }
+    for (auto const & [keyword, required] : permitted_keywords) {
+      EXPECT_M(not required || keyword.starts_with("$") || metadata_.contains(keyword),
+               "Vocabulary Keyword " << keyword << " required, but not implemented");
+    }
   }
 
   schema::Version version() const { return version_; }