فهرست منبع

fix: proper handling of anchors w/ ids, anchors in remote documents

Sam Jaffe 1 سال پیش
والد
کامیت
810f760642
3فایلهای تغییر یافته به همراه14 افزوده شده و 5 حذف شده
  1. 6 0
      include/jvalidate/detail/reference.h
  2. 3 4
      include/jvalidate/reference_handler.h
  3. 5 1
      include/jvalidate/schema.h

+ 6 - 0
include/jvalidate/detail/reference.h

@@ -64,6 +64,12 @@ private:
 public:
 public:
   Reference() = default;
   Reference() = default;
 
 
+  explicit Reference(URI const & uri, Pointer const & pointer = {})
+      : root_(uri), pointer_(pointer) {}
+
+  explicit Reference(URI const & uri, Anchor const & anchor, Pointer const & pointer = {})
+      : root_(uri, anchor), pointer_(pointer) {}
+
   explicit Reference(RootReference const & root, Pointer const & pointer = {})
   explicit Reference(RootReference const & root, Pointer const & pointer = {})
       : root_(root), pointer_(pointer) {}
       : root_(root), pointer_(pointer) {}
 
 

+ 3 - 4
include/jvalidate/reference_handler.h

@@ -85,15 +85,15 @@ public:
       uri = (uri.is_relative() ? parent_uri.parent() : parent_uri.root()) / uri;
       uri = (uri.is_relative() ? parent_uri.parent() : parent_uri.root()) / uri;
     }
     }
 
 
-    detail::Reference rval(detail::RootReference(uri, ref.anchor()), ref.pointer());
+    detail::Reference rval(uri, ref.anchor(), ref.pointer());
 
 
     // Will now need to go make an external fetch...
     // Will now need to go make an external fetch...
     // TODO(samjaffe): Make that process internal?
     // TODO(samjaffe): Make that process internal?
     return rval;
     return rval;
   }
   }
 
 
-  void prime(Adapter auto const & json, detail::RootReference const & where,
-             schema::Version version, Keywords const & keywords) {
+  void prime(Adapter auto const & json, URI const & where, schema::Version version,
+             Keywords const & keywords) {
     canonical_to_absolute_.emplace(where, detail::Reference(where));
     canonical_to_absolute_.emplace(where, detail::Reference(where));
     prime_impl(json, detail::Reference(where), version, keywords);
     prime_impl(json, detail::Reference(where), version, keywords);
   }
   }
@@ -154,7 +154,6 @@ private:
       return;
       return;
     }
     }
 
 
-    EXPECT_M(root.anchor().empty(), "Cannot have $id with anchor and $anchor tags at same time");
     root = detail::RootReference(root.uri(), detail::Anchor(schema["$anchor"].as_string()));
     root = detail::RootReference(root.uri(), detail::Anchor(schema["$anchor"].as_string()));
 
 
     cache(root, where, json);
     cache(root, where, json);

+ 5 - 1
include/jvalidate/schema.h

@@ -273,9 +273,13 @@ private:
       return alias(ref, &cache_.try_emplace(ref, error).first->second);
       return alias(ref, &cache_.try_emplace(ref, error).first->second);
     }
     }
 
 
-    context.ref.prime(*schema, ref.root(), context.version,
+    context.ref.prime(*schema, ref.uri(), context.version,
                       context.factory.keywords(context.version));
                       context.factory.keywords(context.version));
     ref = context.ref.canonicalize(ref, context.where);
     ref = context.ref.canonicalize(ref, context.where);
+    if (std::optional root = context.ref.root(ref.root())) {
+      return fetch_schema(context.rebind(ref.pointer().walk(*root), ref));
+    }
+
     return fetch_schema(context.rebind(ref.pointer().walk(*schema), ref));
     return fetch_schema(context.rebind(ref.pointer().walk(*schema), ref));
   }
   }