Procházet zdrojové kódy

refactor: add other edge case to RelativePointer (no hash, no ptr)

Sam Jaffe před 3 měsíci
rodič
revize
1dea9695c7
1 změnil soubory, kde provedl 24 přidání a 6 odebrání
  1. 24 6
      include/jvalidate/detail/relative_pointer.h

+ 24 - 6
include/jvalidate/detail/relative_pointer.h

@@ -1,5 +1,6 @@
 #pragma once
 
+#include <ostream>
 #include <string>
 #include <string_view>
 
@@ -11,12 +12,16 @@ namespace jvalidate::detail {
 class RelativePointer {
 public:
   RelativePointer(std::string_view path) {
+    if (path == "0") {
+      return;
+    }
     if (auto pos = path.find('/'); pos != path.npos) {
       pointer_ = Pointer(path.substr(pos));
       path.remove_suffix(path.size() - pos);
     } else {
       EXPECT_M(not path.empty() && path.back() == '#',
-               "RelativePointer must end in a pointer, or a '#'")
+               "RelativePointer must end in a pointer, or a '#'");
+      requests_key_ = true;
       path.remove_suffix(1);
     }
     parent_steps_ = std::stoull(std::string(path));
@@ -24,14 +29,27 @@ public:
 
   template <Adapter A>
   std::variant<std::string, A> inspect(Pointer const & where, A const & root) const {
-    if (pointer_) {
-      return pointer_->walk(where.parent(parent_steps_).walk(root));
+    if (requests_key_) {
+      return where.parent(parent_steps_).back();
+    }
+    auto rval = where.parent(parent_steps_).walk(root);
+    return pointer_ ? pointer_->walk(rval) : rval;
+  }
+
+  friend std::ostream & operator<<(std::ostream & os, RelativePointer const & rel) {
+    os << rel.parent_steps_;
+    if (rel.requests_key_) {
+      return os << '#';
+    }
+    if (rel.pointer_) {
+      os << *rel.pointer_;
     }
-    return where.parent(parent_steps_).back();
+    return os;
   }
 
 private:
-  size_t parent_steps_;
-  std::optional<Pointer> pointer_;
+  size_t parent_steps_ = 0;
+  bool requests_key_ = false;
+  std::optional<Pointer> pointer_ = std::nullopt;
 };
 }