Explorar o código

refactor: add keyword info to allow pre-searching $id/$anchor info

Sam Jaffe hai 1 ano
pai
achega
ac8bfd6b54
Modificáronse 2 ficheiros con 50 adicións e 3 borrados
  1. 48 3
      include/jvalidate/constraint.h
  2. 2 0
      include/jvalidate/enum.h

+ 48 - 3
include/jvalidate/constraint.h

@@ -26,13 +26,14 @@ public:
   using Object = decltype(std::declval<A>().as_object());
 
   using MakeConstraint = std::function<pConstraint(detail::ParserContext<A> const &)>;
-  using VersionedMakeConstraint = std::map<schema::Version, MakeConstraint, std::greater<>>;
+  template <typename V> using Versioned = std::map<schema::Version, V, std::greater<>>;
+  template <typename V> using Keywords = std::unordered_map<std::string_view, V>;
 
 private:
   using Self = ConstraintFactory<A>;
 
 private:
-  std::unordered_map<std::string_view, MakeConstraint> constraints_{
+  Keywords<MakeConstraint> constraints_{
       {"additionalProperties", &Self::additionalProperties},
       {"enum", &Self::isInEnumuration},
       {"maxItems", &Self::maxItems},
@@ -48,7 +49,7 @@ private:
       {"uniqueItems", &Self::uniqueItems},
   };
 
-  std::unordered_map<std::string_view, VersionedMakeConstraint> versioned_constraints_{
+  Keywords<Versioned<MakeConstraint>> versioned_constraints_{
       {"additionalItems",
        {{schema::Version::Draft04, &Self::additionalItems},
         {schema::Version::Draft2020_12, nullptr}}},
@@ -84,11 +85,55 @@ private:
       {"unevaluatedProperties", {{schema::Version::Draft2019_09, &Self::unevaluatedProperties}}},
   };
 
+  Keywords<Versioned<std::set<schema::Wraps>>> keywords_{
+      {"$defs", {{schema::Version::Draft2019_09, {schema::Wraps::Object}}}},
+      {"additionalItems",
+       {{schema::Version::Draft04, {schema::Wraps::Schema}}, {schema::Version::Draft2020_12, {}}}},
+      {"additionalProperties", {{schema::Version::Draft04, {schema::Wraps::Schema}}}},
+      {"allOf", {{schema::Version::Draft04, {schema::Wraps::Array}}}},
+      {"anyOf", {{schema::Version::Draft04, {schema::Wraps::Array}}}},
+      {"definitions",
+       {{schema::Version::Draft04, {schema::Wraps::Object}}, {schema::Version::Draft2019_09, {}}}},
+      {"dependencies",
+       {{schema::Version::Draft04, {schema::Wraps::Object}}, {schema::Version::Draft2019_09, {}}}},
+      {"dependentSchemas", {{schema::Version::Draft2019_09, {schema::Wraps::Object}}}},
+      {"items",
+       {{schema::Version::Draft04, {schema::Wraps::Array, schema::Wraps::Schema}},
+        {schema::Version::Draft2020_12, {schema::Wraps::Schema}}}},
+      {"not", {{schema::Version::Draft04, {schema::Wraps::Schema}}}},
+      {"oneOf", {{schema::Version::Draft04, {schema::Wraps::Array}}}},
+      {"patternProperties", {{schema::Version::Draft04, {schema::Wraps::Object}}}},
+      {"prefixItems", {{schema::Version::Draft2020_12, {schema::Wraps::Array}}}},
+      {"properties", {{schema::Version::Draft04, {schema::Wraps::Object}}}},
+      {"unevaluatedItems", {{schema::Version::Draft2020_12, {schema::Wraps::Schema}}}},
+      {"unevaluatedProperties", {{schema::Version::Draft2020_12, {schema::Wraps::Schema}}}},
+  };
+
 public:
+  ConstraintFactory() = default;
+
+  explicit ConstraintFactory(
+      Keywords<MakeConstraint> const & user_keywords,
+      Keywords<Versioned<MakeConstraint>> const & user_versioned_keywords = {}) {
+    constraints_.insert(constraints_.end(), user_keywords.begin(), user_keywords.end());
+    versioned_constraints_.insert(versioned_constraints_.end(), user_versioned_keywords.begin(),
+                                  user_versioned_keywords.end());
+  }
+
   bool is_post_constraint(std::string_view key) const {
     return key == "unevaluatedItems" || key == "unevaluatedProperties";
   }
 
+  Keywords<std::set<schema::Wraps>> keywords(schema::Version version) const {
+    Keywords<std::set<schema::Wraps>> rval;
+    for (auto const & [key, versions] : keywords_) {
+      if (auto it = versions.lower_bound(version); it != versions.end()) {
+        rval.emplace(key, it->second);
+      }
+    }
+    return rval;
+  }
+
   MakeConstraint operator()(std::string_view key, schema::Version version) const {
     if (auto it = constraints_.find(key); it != constraints_.end()) {
       return it->second;

+ 2 - 0
include/jvalidate/enum.h

@@ -63,4 +63,6 @@ enum class Version : int {
   // https://json-schema.org/draft/2020-12/schema
   Draft2020_12,
 };
+
+enum class Wraps : int8_t { Array, Object, Schema };
 }